Latest Sync

This commit is contained in:
Speiger 2023-05-19 21:26:57 +02:00
parent c95e7ce20d
commit b42e680b8a
63 changed files with 13681 additions and 12857 deletions

View File

@ -1,70 +1,69 @@
apply plugin: 'java'
apply plugin: 'eclipse'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
options.compilerArgs << "-Xlint:deprecation"
}
eclipse {
classpath {
downloadJavadoc = true
downloadSources = true
}
}
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven {
url = "https://maven.speiger.com/repository/main"
}
}
task srcJar(type: Jar) {
from sourceSets.main.allSource
classifier = 'sources'
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
artifacts {
archives srcJar
}
jar{
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
dependencies {
//LWJGL 3
compile platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
compile "org.lwjgl:lwjgl"
compile "org.lwjgl:lwjgl-glfw"
compile "org.lwjgl:lwjgl-jemalloc"
compile "org.lwjgl:lwjgl-openal"
compile "org.lwjgl:lwjgl-opengl"
compile "org.lwjgl:lwjgl-stb"
compile "org.lwjgl:lwjgl-nfd"
compile "org.lwjgl:lwjgl::$lwjglNatives"
compile "org.lwjgl:lwjgl-glfw::$lwjglNatives"
compile "org.lwjgl:lwjgl-jemalloc::$lwjglNatives"
compile "org.lwjgl:lwjgl-openal::$lwjglNatives"
compile "org.lwjgl:lwjgl-opengl::$lwjglNatives"
compile "org.lwjgl:lwjgl-stb::$lwjglNatives"
compile "org.lwjgl:lwjgl-nfd::$lwjglNatives"
//Gson
compile 'com.google.code.gson:gson:2.8.6'
//Primitive Collections
compile 'de.speiger:Primitive-Collections:0.6.1'
apply plugin: 'java'
apply plugin: 'eclipse'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
eclipse {
classpath {
downloadJavadoc = true
downloadSources = true
}
}
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven {
url = "https://maven.speiger.com/repository/main"
}
}
task srcJar(type: Jar) {
from sourceSets.main.allSource
classifier = 'sources'
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
artifacts {
archives srcJar
}
jar{
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
dependencies {
//LWJGL 3
compile platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
compile "org.lwjgl:lwjgl"
compile "org.lwjgl:lwjgl-glfw"
compile "org.lwjgl:lwjgl-jemalloc"
compile "org.lwjgl:lwjgl-openal"
compile "org.lwjgl:lwjgl-opengl"
compile "org.lwjgl:lwjgl-stb"
compile "org.lwjgl:lwjgl-nfd"
compile "org.lwjgl:lwjgl::$lwjglNatives"
compile "org.lwjgl:lwjgl-glfw::$lwjglNatives"
compile "org.lwjgl:lwjgl-jemalloc::$lwjglNatives"
compile "org.lwjgl:lwjgl-openal::$lwjglNatives"
compile "org.lwjgl:lwjgl-opengl::$lwjglNatives"
compile "org.lwjgl:lwjgl-stb::$lwjglNatives"
compile "org.lwjgl:lwjgl-nfd::$lwjglNatives"
//Gson
compile 'com.google.code.gson:gson:2.8.6'
//Primitive Collections
compile 'de.speiger:Primitive-Collections:0.7.0'
}

View File

@ -1,143 +1,143 @@
package speiger.src.coreengine.application;
import java.text.DecimalFormat;
import org.lwjgl.opengl.GL11;
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
import speiger.src.collections.objects.queues.ObjectPriorityQueue;
import speiger.src.coreengine.rendering.input.window.Window;
import speiger.src.coreengine.rendering.utils.AllocationTracker;
import speiger.src.coreengine.rendering.utils.GLStamper;
import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp;
import speiger.src.coreengine.rendering.utils.GLUtils;
import speiger.src.coreengine.utils.counters.averager.TimeAverager;
import speiger.src.coreengine.utils.counters.timers.FPSTimer;
import speiger.src.coreengine.utils.counters.timers.FrameSyncer;
import speiger.src.coreengine.utils.counters.timers.TimerTarget;
import speiger.src.coreengine.utils.helpers.FileUtils;
import speiger.src.coreengine.utils.helpers.TextUtil;
import speiger.src.coreengine.utils.io.GameLog;
import speiger.src.coreengine.utils.io.GameLog.LogLevel;
import speiger.src.coreengine.utils.profiler.IProfiler;
public class ApplicationExecutor
{
public static final DecimalFormat FORMATTER = new DecimalFormat("###");
FPSTimer timer = new FPSTimer();
TimerTarget fps = timer.getFPS();
TimerTarget ups = timer.getUPS();
FrameSyncer sync = new FrameSyncer();
TimeAverager gpuTime = new TimeAverager();
ObjectPriorityQueue<GLStamp> stamps = new ObjectArrayFIFOQueue<>();
StringBuilder builder = new StringBuilder();
long frame = 0L;
Application owner;
public ApplicationExecutor(Application owner)
{
this.owner = owner;
owner.timer = timer;
}
private IProfiler gpu()
{
return owner.gpuProfiler;
}
public void start(Window window)
{
createTimeHacker();
timer.init();
try
{
while(window.shouldRun()) loop(window);
}
catch(Exception e)
{
GameLog.error("Client Has Crashed", e, LogLevel.ERROR);
}
}
private void loop(Window window)
{
GLStamp stamp = GLStamper.INSTANCE.createStamp("MainStamp").start();
stamps.enqueue(stamp);
gpu().start("Client").start("Update");
window.update();
for(long f = timer.getDelta();f >= ups.getTargetNS();f = timer.consumeDelta())
{
ups.tick();
owner.updateInternal();
builder.setLength(0);
builder.append(owner.getMainWindowName());
if(owner.showProfilingInfo) addDebugInfo(builder);
window.setTitle(builder.toString());
}
gpu().next("Render");
render(timer.getParticalTime());
gpu().next("Trackers");
boolean end = timer.update();
stamp.stop();
AllocationTracker.INSTANCE.update();
GLUtils.onFrameEnded();
gpu().next("Window").start("V-Sync");
window.finishFrame();
if(window.isCPULimited()) sync.sync(fps.getTargetTicks());
gpu().next("Input");
window.gatherInputs();
gpu().stop().stop().stop().onFrameEnded(end);
while(!stamps.isEmpty() && stamps.first().isFinished())
{
stamp = stamps.dequeue();
gpuTime.addEntry(stamp.getResult());
stamp.release();
}
frame++;
}
private void render(float particalTicks)
{
gpu().start("Prep");
fps.tick();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
gpu().stop();
owner.renderInternal(particalTicks);
}
public void createTimeHacker()
{
Thread thread = new Thread(() -> {
while (true){
try {Thread.sleep(2147483647L);}
catch (InterruptedException e){}
}
}, "Time Fixer Thread");
thread.setDaemon(true);
thread.start();
}
protected void addDebugInfo(StringBuilder builder)
{
builder.append("(");
builder.append(fps.getTicks()).append(":").append(ups.getTicks());
owner.addExtraTickRates(T -> builder.append(":").append(T));
builder.append(",").append(getMemoryUsage());
builder.append(",").append("CPU-A: "+FileUtils.convertBytes(AllocationTracker.INSTANCE.getCPUAllocatedBytes()));
builder.append(",").append("GPU-A: "+FileUtils.convertBytes(AllocationTracker.INSTANCE.getGPUAllocatedBytes()));
builder.append(",").append(TextUtil.convertTime(timer.getUsage(), "Client:", FORMATTER));
builder.append(",").append(TextUtil.convertTime(gpuTime.getAverage(), "GPU:", FORMATTER));
owner.addExtraTimers((N, T) -> builder.append(",").append(TextUtil.convertTime(T, N, FORMATTER)));
builder.append(")");
}
private String getMemoryUsage()
{
Runtime time = Runtime.getRuntime();
long aviable = time.totalMemory();
return "Memory:"+((aviable - time.freeMemory()) >> 20)+"MB/"+(aviable >> 20)+"MB";
}
}
package speiger.src.coreengine.application;
import java.text.DecimalFormat;
import org.lwjgl.opengl.GL11;
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
import speiger.src.collections.objects.queues.ObjectPriorityQueue;
import speiger.src.coreengine.rendering.input.window.Window;
import speiger.src.coreengine.rendering.utils.AllocationTracker;
import speiger.src.coreengine.rendering.utils.GLStamper;
import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp;
import speiger.src.coreengine.rendering.utils.GLUtils;
import speiger.src.coreengine.utils.counters.averager.TimeAverager;
import speiger.src.coreengine.utils.counters.timers.FPSTimer;
import speiger.src.coreengine.utils.counters.timers.FrameSyncer;
import speiger.src.coreengine.utils.counters.timers.TimerTarget;
import speiger.src.coreengine.utils.helpers.FileUtils;
import speiger.src.coreengine.utils.helpers.TextUtil;
import speiger.src.coreengine.utils.io.GameLog;
import speiger.src.coreengine.utils.io.GameLog.LogLevel;
import speiger.src.coreengine.utils.profiler.IProfiler;
public class ApplicationExecutor
{
public static final DecimalFormat FORMATTER = new DecimalFormat("###");
FPSTimer timer = new FPSTimer();
TimerTarget fps = timer.getFPS();
TimerTarget ups = timer.getUPS();
FrameSyncer sync = new FrameSyncer();
TimeAverager gpuTime = new TimeAverager();
ObjectPriorityQueue<GLStamp> stamps = new ObjectArrayFIFOQueue<>();
StringBuilder builder = new StringBuilder();
long frame = 0L;
Application owner;
public ApplicationExecutor(Application owner)
{
this.owner = owner;
owner.timer = timer;
}
private IProfiler gpu()
{
return owner.gpuProfiler;
}
public void start(Window window)
{
createTimeHacker();
timer.init();
try
{
while(window.shouldRun()) loop(window);
}
catch(Exception e)
{
GameLog.error("Client Has Crashed", e, LogLevel.ERROR);
}
}
private void loop(Window window)
{
GLStamp stamp = GLStamper.INSTANCE.createStamp("MainStamp").start();
stamps.enqueue(stamp);
gpu().start("Client").start("Update");
window.update();
for(long f = timer.getDelta();f >= ups.getTargetNS();f = timer.consumeDelta())
{
ups.tick();
owner.updateInternal();
builder.setLength(0);
builder.append(owner.getMainWindowName());
if(owner.showProfilingInfo) addDebugInfo(builder);
window.setTitle(builder.toString());
}
gpu().next("Render");
render(timer.getParticalTime());
gpu().next("Trackers");
boolean end = timer.update();
stamp.stop();
AllocationTracker.INSTANCE.update();
GLUtils.onFrameEnded();
gpu().next("Window").start("V-Sync");
window.finishFrame();
if(window.isCPULimited()) sync.sync(fps.getTargetTicks());
gpu().next("Input");
window.gatherInputs();
gpu().stop().stop().stop().onFrameEnded(end);
while(!stamps.isEmpty() && stamps.first().isFinished())
{
stamp = stamps.dequeue();
gpuTime.addEntry(stamp.getResult());
stamp.release();
}
frame++;
}
private void render(float particalTicks)
{
gpu().start("Prep");
fps.tick();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
gpu().stop();
owner.renderInternal(particalTicks);
}
public void createTimeHacker()
{
Thread thread = new Thread(() -> {
while (true){
try {Thread.sleep(2147483647L);}
catch (InterruptedException e){}
}
}, "Time Fixer Thread");
thread.setDaemon(true);
thread.start();
}
protected void addDebugInfo(StringBuilder builder)
{
builder.append("(");
builder.append(fps.getTicks()).append(":").append(ups.getTicks());
owner.addExtraTickRates(T -> builder.append(":").append(T));
builder.append(",").append(getMemoryUsage());
builder.append(",").append("CPU-A: "+FileUtils.convertBytes(AllocationTracker.INSTANCE.getCPUAllocatedBytes()));
builder.append(",").append("GPU-A: "+FileUtils.convertBytes(AllocationTracker.INSTANCE.getGPUAllocatedBytes()));
builder.append(",").append(TextUtil.convertTime(timer.getUsage(), "Client:", FORMATTER));
builder.append(",").append(TextUtil.convertTime(gpuTime.getAverage(), "GPU:", FORMATTER));
owner.addExtraTimers((N, T) -> builder.append(",").append(TextUtil.convertTime(T, N, FORMATTER)));
builder.append(")");
}
private String getMemoryUsage()
{
Runtime time = Runtime.getRuntime();
long aviable = time.totalMemory();
return "Memory:"+((aviable - time.freeMemory()) >> 20)+"MB/"+(aviable >> 20)+"MB";
}
}

View File

@ -1,278 +1,278 @@
package speiger.src.coreengine.rendering.gui;
import org.lwjgl.opengl.GL11;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.math.vector.ints.Vec2i;
import speiger.src.coreengine.rendering.gui.base.DebugOverlay;
import speiger.src.coreengine.rendering.gui.renderer.FontRenderer;
import speiger.src.coreengine.rendering.gui.renderer.GuiShader;
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
import speiger.src.coreengine.rendering.gui.renderer.provider.FontManager;
import speiger.src.coreengine.rendering.input.events.KeyEvent.CharTypeEvent;
import speiger.src.coreengine.rendering.input.events.KeyEvent.KeyPressEvent;
import speiger.src.coreengine.rendering.input.events.MouseEvent;
import speiger.src.coreengine.rendering.input.window.IWindowListener;
import speiger.src.coreengine.rendering.input.window.ScaledResolution;
import speiger.src.coreengine.rendering.input.window.Window;
import speiger.src.coreengine.rendering.models.UniformBuffer;
import speiger.src.coreengine.rendering.shader.ShaderTracker;
import speiger.src.coreengine.rendering.utils.Cursor;
import speiger.src.coreengine.rendering.utils.GLUtils;
import speiger.src.coreengine.utils.eventbus.EventBus;
import speiger.src.coreengine.utils.profiler.IProfiler;
public abstract class GuiManager implements IWindowListener
{
protected GuiBase[] activeGuis = new GuiBase[2];
protected GuiBase gui;
protected DebugOverlay debug;
protected UIRenderer renderer = new UIRenderer(this);
protected Window window;
protected ScaledResolution res;
protected long globalClock = 0L;
protected boolean isReloading = false;
protected FontRenderer font;
protected GuiShader shader = ShaderTracker.INSTANCE.register(GuiShader::create, T -> shader = T);
public GuiManager(Window window, EventBus bus, FontManager manager)
{
this.window = window;
font = manager.loadFont(AssetLocation.of("font/roboto.json"), 18.5F);
bus.register(MouseEvent.class, this::onMouseEvent);
bus.register(KeyPressEvent.class, (T) -> T.setCanceled(onKeyPressed(T.key)));
bus.register(CharTypeEvent.class, (T) -> T.setCanceled(onCharTyped(T.character, T.codePoint)));
window.addListener(this, false);
debug = createOverlay();
activeGuis[1] = debug;
res = window.getUIFrame();
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
debug.onInit();
}
public abstract IProfiler getGPUProfiler();
public abstract IProfiler getCPUProfiler();
public abstract IProfiler getServerProfiler();
public abstract UniformBuffer getOrthoMatrixBuffer();
public abstract DebugOverlay createOverlay();
public void showGui(GuiBase base, boolean allowBack)
{
if(allowBack)
{
base.setLastGui(gui);
}
closeGui();
gui = base;
if(gui != null)
{
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
gui.onInit();
if(activeGuis[0] != null)
{
activeGuis[1] = activeGuis[0];
}
activeGuis[0] = base;
}
if(activeGuis[0] != null)
{
activeGuis[0].focus = true;
}
if(activeGuis[1] != null)
{
activeGuis[1].focus = false;
}
}
public void closeGui()
{
if(gui != null)
{
if(gui == activeGuis[0])
{
activeGuis[0] = null;
}
if(gui == activeGuis[1])
{
activeGuis[1] = null;
}
gui.onClosed();
gui = null;
}
}
@Override
public void onWindowChanged(Window window)
{
if(gui != null)
{
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
gui.onScreenChanged();
}
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
debug.onScreenChanged();
}
public void onFixedUpdate()
{
globalClock++;
for(int i = 0;i < 2;i++)
{
if(activeGuis[i] != null)
{
activeGuis[i].onFixedUpdate();
}
}
}
public void render(float particalTicks)
{
Vec2i offsetMouse = start();
if(debug.isUpdating() || isReloading)
{
isReloading = false;
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
debug.onScreenChanged();
if(gui != null)
{
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
gui.onScreenChanged();
}
}
if(activeGuis[0] != null)
{
activeGuis[0].baseLayer = activeGuis[1] != null ? activeGuis[1].layers : 0;
}
for(int i = 1;i >= 0;i--)
{
if(activeGuis[i] != null && (activeGuis[i] instanceof DebugOverlay || debug.isRendering()))
{
activeGuis[i].draw(offsetMouse.getX(), offsetMouse.getY(), particalTicks);
}
}
stop();
Cursor.INSTANCE.clearCursor(window);
}
protected Vec2i start()
{
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
GLUtils.DEBTH_TEST.push(false);
GLUtils.CULL_FACE.push(false);
GLUtils.BLEND.setFunction(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA).push(true);
renderer.beginFrame();
return res.getScaledMouse();
}
protected void stop()
{
GLUtils.DEBTH_TEST.pop();
GLUtils.DEBTH_TEST.push(true);
renderer.endFrame();
GLUtils.BLEND.pop();
GLUtils.CULL_FACE.pop();
ShaderTracker.INSTANCE.stopShader();
}
public boolean onCharTyped(char character, int codePoint)
{
for(int i = 0;i < 2;i++)
{
if(activeGuis[i] != null && debug.shouldAcceptInputs(activeGuis[i]) && activeGuis[i].onKeyTyped(character, codePoint))
{
return true;
}
}
return false;
}
public boolean onKeyPressed(int key)
{
for(int i = 0;i < 2;i++)
{
if(activeGuis[i] != null && debug.shouldAcceptInputs(activeGuis[i]) && activeGuis[i].onKeyPressed(key))
{
return true;
}
}
return false;
}
public void onMouseEvent(MouseEvent event)
{
if(!onMouseEventInternal(event))
{
return;
}
if(activeGuis[0] != null && !event.isCanceled() && debug.shouldAcceptInputs(activeGuis[0]))
{
activeGuis[0].onMouseEvent(event);
}
if(activeGuis[1] != null && !event.isCanceled() && debug.shouldAcceptInputs(activeGuis[1]))
{
activeGuis[1].onMouseEvent(event);
if(event.isCanceled())
{
GuiBase base = activeGuis[0];
activeGuis[0] = activeGuis[1];
activeGuis[1] = base;
if(base != null)
{
base.onFocusLost();
base.baseLayer = 0;
base.layers = 0;
}
if(activeGuis[0] != null)
{
activeGuis[0].focus = true;
}
if(activeGuis[1] != null)
{
activeGuis[1].focus = false;
}
}
}
event.convertToOrigin();
}
protected boolean onMouseEventInternal(MouseEvent event)
{
event.convertToScreenCoords(res);
return true;
}
public boolean isAllowingMovement()
{
return gui == null || gui.isAllowingMovement();
}
public DebugOverlay getDebug()
{
return debug;
}
public boolean isRenderUIBoxes()
{
return false;
}
public GuiShader getShader()
{
return shader;
}
public UIRenderer getRenderer()
{
return renderer;
}
public FontRenderer getFont()
{
return font;
}
public ScaledResolution getRes()
{
return res;
}
}
package speiger.src.coreengine.rendering.gui;
import org.lwjgl.opengl.GL11;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.math.vector.ints.Vec2i;
import speiger.src.coreengine.rendering.gui.base.DebugOverlay;
import speiger.src.coreengine.rendering.gui.renderer.FontRenderer;
import speiger.src.coreengine.rendering.gui.renderer.GuiShader;
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
import speiger.src.coreengine.rendering.gui.renderer.provider.FontManager;
import speiger.src.coreengine.rendering.input.events.KeyEvent.CharTypeEvent;
import speiger.src.coreengine.rendering.input.events.KeyEvent.KeyPressEvent;
import speiger.src.coreengine.rendering.input.events.MouseEvent;
import speiger.src.coreengine.rendering.input.window.IWindowListener;
import speiger.src.coreengine.rendering.input.window.ScaledResolution;
import speiger.src.coreengine.rendering.input.window.Window;
import speiger.src.coreengine.rendering.models.UniformBuffer;
import speiger.src.coreengine.rendering.shader.ShaderTracker;
import speiger.src.coreengine.rendering.utils.Cursor;
import speiger.src.coreengine.rendering.utils.GLUtils;
import speiger.src.coreengine.utils.eventbus.EventBus;
import speiger.src.coreengine.utils.profiler.IProfiler;
public abstract class GuiManager implements IWindowListener
{
protected GuiBase[] activeGuis = new GuiBase[2];
protected GuiBase gui;
protected DebugOverlay debug;
protected UIRenderer renderer = new UIRenderer(this);
protected Window window;
protected ScaledResolution res;
protected long globalClock = 0L;
protected boolean isReloading = false;
protected FontRenderer font;
protected GuiShader shader = ShaderTracker.INSTANCE.register(GuiShader::create, T -> shader = T);
public GuiManager(Window window, EventBus bus, FontManager manager)
{
this.window = window;
font = manager.loadFont(AssetLocation.of("font/roboto.json"), 18.5F);
bus.register(MouseEvent.class, this::onMouseEvent);
bus.register(KeyPressEvent.class, (T) -> T.setCanceled(onKeyPressed(T.key)));
bus.register(CharTypeEvent.class, (T) -> T.setCanceled(onCharTyped(T.character, T.codePoint)));
window.addListener(this, false);
debug = createOverlay();
activeGuis[1] = debug;
res = window.getUIFrame();
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
debug.onInit();
}
public abstract IProfiler getGPUProfiler();
public abstract IProfiler getCPUProfiler();
public abstract IProfiler getServerProfiler();
public abstract UniformBuffer getOrthoMatrixBuffer();
public abstract DebugOverlay createOverlay();
public void showGui(GuiBase base, boolean allowBack)
{
if(allowBack)
{
base.setLastGui(gui);
}
closeGui();
gui = base;
if(gui != null)
{
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
gui.onInit();
if(activeGuis[0] != null)
{
activeGuis[1] = activeGuis[0];
}
activeGuis[0] = base;
}
if(activeGuis[0] != null)
{
activeGuis[0].focus = true;
}
if(activeGuis[1] != null)
{
activeGuis[1].focus = false;
}
}
public void closeGui()
{
if(gui != null)
{
if(gui == activeGuis[0])
{
activeGuis[0] = null;
}
if(gui == activeGuis[1])
{
activeGuis[1] = null;
}
gui.onClosed();
gui = null;
}
}
@Override
public void onWindowChanged(Window window)
{
if(gui != null)
{
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
gui.onScreenChanged();
}
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
debug.onScreenChanged();
}
public void onFixedUpdate()
{
globalClock++;
for(int i = 0;i < 2;i++)
{
if(activeGuis[i] != null)
{
activeGuis[i].onFixedUpdate();
}
}
}
public void render(float particalTicks)
{
Vec2i offsetMouse = start();
if(debug.isUpdating() || isReloading)
{
isReloading = false;
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
debug.onScreenChanged();
if(gui != null)
{
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
gui.onScreenChanged();
}
}
if(activeGuis[0] != null)
{
activeGuis[0].baseLayer = activeGuis[1] != null ? activeGuis[1].layers : 0;
}
for(int i = 1;i >= 0;i--)
{
if(activeGuis[i] != null && (activeGuis[i] instanceof DebugOverlay || debug.isRendering()))
{
activeGuis[i].draw(offsetMouse.getX(), offsetMouse.getY(), particalTicks);
}
}
stop();
Cursor.INSTANCE.clearCursor(window);
}
protected Vec2i start()
{
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
GLUtils.DEBTH_TEST.push(false);
GLUtils.CULL_FACE.push(false);
GLUtils.BLEND.setFunction(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA).push(true);
renderer.beginFrame();
return res.getScaledMouse();
}
protected void stop()
{
GLUtils.DEBTH_TEST.pop();
GLUtils.DEBTH_TEST.push(true);
renderer.endFrame();
GLUtils.BLEND.pop();
GLUtils.CULL_FACE.pop();
ShaderTracker.INSTANCE.stopShader();
}
public boolean onCharTyped(char character, int codePoint)
{
for(int i = 0;i < 2;i++)
{
if(activeGuis[i] != null && debug.shouldAcceptInputs(activeGuis[i]) && activeGuis[i].onKeyTyped(character, codePoint))
{
return true;
}
}
return false;
}
public boolean onKeyPressed(int key)
{
for(int i = 0;i < 2;i++)
{
if(activeGuis[i] != null && debug.shouldAcceptInputs(activeGuis[i]) && activeGuis[i].onKeyPressed(key))
{
return true;
}
}
return false;
}
public void onMouseEvent(MouseEvent event)
{
if(!onMouseEventInternal(event))
{
return;
}
if(activeGuis[0] != null && !event.isCanceled() && debug.shouldAcceptInputs(activeGuis[0]))
{
activeGuis[0].onMouseEvent(event);
}
if(activeGuis[1] != null && !event.isCanceled() && debug.shouldAcceptInputs(activeGuis[1]))
{
activeGuis[1].onMouseEvent(event);
if(event.isCanceled())
{
GuiBase base = activeGuis[0];
activeGuis[0] = activeGuis[1];
activeGuis[1] = base;
if(base != null)
{
base.onFocusLost();
base.baseLayer = 0;
base.layers = 0;
}
if(activeGuis[0] != null)
{
activeGuis[0].focus = true;
}
if(activeGuis[1] != null)
{
activeGuis[1].focus = false;
}
}
}
event.convertToOrigin();
}
protected boolean onMouseEventInternal(MouseEvent event)
{
event.convertToScreenCoords(res);
return true;
}
public boolean isAllowingMovement()
{
return gui == null || gui.isAllowingMovement();
}
public DebugOverlay getDebug()
{
return debug;
}
public boolean isRenderUIBoxes()
{
return false;
}
public GuiShader getShader()
{
return shader;
}
public UIRenderer getRenderer()
{
return renderer;
}
public FontRenderer getFont()
{
return font;
}
public ScaledResolution getRes()
{
return res;
}
}

View File

@ -1,63 +1,73 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
public class ButtonComponent extends GuiComponent implements IButtonComponent
{
TextComponent text = new TextComponent();
int color;
public ButtonComponent(String text, int color)
{
this(0F, 0F, 0F, 0F, text, color);
}
public ButtonComponent(float x, float y, float width, float height, String text, int color)
{
super(x, y, width, height);
this.text.setText(text);
this.color = color;
setFlag(FLAG_SUPPORT_BINDING);
}
@Override
public void init()
{
addChild(text, Constrains.parent());
}
public TextComponent getText()
{
return text;
}
public ButtonComponent setColor(int color)
{
this.color = color;
return this;
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brigthness = getBrightness(mouseX, mouseY);
getRenderer().setBrightness(brigthness).drawQuad(getBox(), color);
text.setBrightness(brigthness);
return true;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
notifyListeners(LISTENER_USER_ACTION);
}
@Override
protected boolean onUserKey()
{
notifyListeners(LISTENER_USER_ACTION);
return true;
}
}
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
public class ButtonComponent extends GuiComponent implements IButtonComponent
{
TextComponent text = new TextComponent();
int color;
public ButtonComponent(String text, int color)
{
this(0F, 0F, 0F, 0F, text, color, 1F);
}
public ButtonComponent(String text, int color, float textScale)
{
this(0F, 0F, 0F, 0F, text, color, textScale);
}
public ButtonComponent(float x, float y, float width, float height, String text, int color)
{
this(x, y, width, height, text, color, 1F);
}
public ButtonComponent(float x, float y, float width, float height, String text, int color, float textScale)
{
super(x, y, width, height);
this.text.setText(text).setTextScale(textScale);
this.color = color;
setFlag(FLAG_SUPPORT_BINDING);
}
@Override
public void init()
{
addChild(text, Constrains.parent());
}
public TextComponent getText()
{
return text;
}
public ButtonComponent setColor(int color)
{
this.color = color;
return this;
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brigthness = getBrightness(mouseX, mouseY);
getRenderer().setBrightness(brigthness).drawQuad(getBox(), color);
text.setBrightness(brigthness);
return true;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
notifyListeners(LISTENER_USER_ACTION);
}
@Override
protected boolean onUserKey()
{
notifyListeners(LISTENER_USER_ACTION);
return true;
}
}

View File

@ -1,122 +1,122 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.components.misc.ICheckBox;
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
public class CheckBoxComponent extends GuiComponent implements IButtonComponent, ICheckBox<CheckBoxComponent>
{
boolean isChecked = false;
int color;
RenderBuffer buffer;
public CheckBoxComponent(int color)
{
super(0F, 0F, 0F, 0F);
setFlag(FLAG_SUPPORT_BINDING);
this.color = color;
}
public CheckBoxComponent(int color, boolean checked)
{
super(0F, 0F, 0F, 0F);
setFlag(FLAG_SUPPORT_BINDING);
this.color = color;
}
public CheckBoxComponent(float x, float y, float width, float height, int color)
{
super(x, y, width, height);
setFlag(FLAG_SUPPORT_BINDING);
this.color = color;
}
public CheckBoxComponent(float x, float y, float width, float height, int color, boolean checked)
{
super(x, y, width, height);
setFlag(FLAG_SUPPORT_BINDING);
this.color = color;
isChecked = checked;
}
@Override
public void init()
{
addCloseListener(buffer = getRenderer().createBuffer());
}
@Override
public final CheckBoxComponent setChecked(boolean isChecked)
{
this.isChecked = isChecked;
return this;
}
public final CheckBoxComponent setColor(int color)
{
if(this.color != color)
{
this.color = color;
onChanged(true);
}
return this;
}
@Override
public boolean isChecked()
{
return isChecked;
}
@Override
protected void repaint()
{
float width = getBox().getWidth();
float height = getBox().getHeight();
buffer.clear();
UIShapes.createCross(buffer, width, height, (width / 3.3F), (height / 5F), color);
UIShapes.createCross(buffer, width, height, (width / 5F), (height / 10F), color);
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brightness = getActiveBrightness();
float centerX = getBox().getCenterX();
float centerY = getBox().getCenterY();
getRenderer().setBrightness(brightness).drawQuad(getBox(), color).setBrightness(brightness * 0.8F).drawFrame(getBox(), color).translate(centerX, centerY);
if(isChecked())
{
getRenderer().setBrightness(brightness * 0.7F).translate(0, 0, 0.001F).drawBuffers(buffer.selectionIterator(1), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.001F);
}
if(isTopHovered(mouseX, mouseY))
{
getRenderer().setBrightness(brightness * 1.3F).translate(0, 0, 0.002F).drawBuffers(buffer.selectionIterator(0), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.002F);
}
getRenderer().setBrightness(1F).translate(-centerX, -centerY);
return true;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
return true;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
isChecked = !isChecked;
notifyListeners(LISTENER_USER_ACTION);
}
@Override
protected boolean onUserKey()
{
isChecked = !isChecked;
notifyListeners(LISTENER_USER_ACTION);
return true;
}
}
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.components.misc.ICheckBox;
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
public class CheckBoxComponent extends GuiComponent implements IButtonComponent, ICheckBox<CheckBoxComponent>
{
boolean isChecked = false;
int color;
RenderBuffer buffer;
public CheckBoxComponent(int color)
{
super(0F, 0F, 0F, 0F);
setFlag(FLAG_SUPPORT_BINDING);
this.color = color;
}
public CheckBoxComponent(int color, boolean checked)
{
super(0F, 0F, 0F, 0F);
setFlag(FLAG_SUPPORT_BINDING);
this.color = color;
}
public CheckBoxComponent(float x, float y, float width, float height, int color)
{
super(x, y, width, height);
setFlag(FLAG_SUPPORT_BINDING);
this.color = color;
}
public CheckBoxComponent(float x, float y, float width, float height, int color, boolean checked)
{
super(x, y, width, height);
setFlag(FLAG_SUPPORT_BINDING);
this.color = color;
isChecked = checked;
}
@Override
public void init()
{
onClose(buffer = getRenderer().createBuffer());
}
@Override
public final CheckBoxComponent setChecked(boolean isChecked)
{
this.isChecked = isChecked;
return this;
}
public final CheckBoxComponent setColor(int color)
{
if(this.color != color)
{
this.color = color;
onChanged(true);
}
return this;
}
@Override
public boolean isChecked()
{
return isChecked;
}
@Override
protected void repaint()
{
float width = getBox().getWidth();
float height = getBox().getHeight();
buffer.clear();
UIShapes.createCross(buffer, width, height, (width / 3.3F), (height / 5F), color);
UIShapes.createCross(buffer, width, height, (width / 5F), (height / 10F), color);
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brightness = getActiveBrightness();
float centerX = getBox().getCenterX();
float centerY = getBox().getCenterY();
getRenderer().setBrightness(brightness).drawQuad(getBox(), color).setBrightness(brightness * 0.8F).drawFrame(getBox(), color).translate(centerX, centerY);
if(isChecked())
{
getRenderer().setBrightness(brightness * 0.7F).translate(0, 0, 0.001F).drawBuffers(buffer.selectionIterator(1), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.001F);
}
if(isTopHovered(mouseX, mouseY))
{
getRenderer().setBrightness(brightness * 1.3F).translate(0, 0, 0.002F).drawBuffers(buffer.selectionIterator(0), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.002F);
}
getRenderer().setBrightness(1F).translate(-centerX, -centerY);
return true;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
return true;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
isChecked = !isChecked;
notifyListeners(LISTENER_USER_ACTION);
}
@Override
protected boolean onUserKey()
{
isChecked = !isChecked;
notifyListeners(LISTENER_USER_ACTION);
return true;
}
}

View File

@ -1,51 +1,61 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
public class LabelComponent extends GuiComponent
{
TextComponent text = new TextComponent();
int color;
public LabelComponent(String text, int color)
{
this(0F, 0F, 0F, 0F, text, color);
}
public LabelComponent(float x, float y, float width, float height, String text, int color)
{
super(x, y, width, height);
this.text.setText(text);
this.color = color;
}
public TextComponent getText()
{
return text;
}
public LabelComponent setColor(int color)
{
this.color = color;
return this;
}
public int getColor()
{
return color;
}
@Override
public void init()
{
addChild(text, Constrains.parent());
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
getRenderer().drawQuad(getBox(), color);
return true;
}
}
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
public class LabelComponent extends GuiComponent
{
TextComponent text = new TextComponent();
int color;
public LabelComponent(String text, int color)
{
this(0F, 0F, 0F, 0F, text, color);
}
public LabelComponent(String text, int color, float textScale)
{
this(0F, 0F, 0F, 0F, text, color, textScale);
}
public LabelComponent(float x, float y, float width, float height, String text, int color)
{
this(x, y, width, height, text, color, 1F);
}
public LabelComponent(float x, float y, float width, float height, String text, int color, float textScale)
{
super(x, y, width, height);
this.text.setText(text).setTextScale(textScale);
this.color = color;
}
public TextComponent getText()
{
return text;
}
public LabelComponent setColor(int color)
{
this.color = color;
return this;
}
public int getColor()
{
return color;
}
@Override
public void init()
{
addChild(text, Constrains.parent());
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
getRenderer().drawQuad(getBox(), color);
return true;
}
}

View File

@ -1,21 +1,47 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent;
public class PanelComponent extends GuiComponent
{
public PanelComponent()
{
super(0F, 0F, 0F, 0F);
}
public PanelComponent(float x, float y, float width, float height)
{
super(x, y, width, height);
}
@Override
public void init()
{
}
}
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent;
public class PanelComponent extends GuiComponent
{
public static final int FLAG_ENABLE_SCISSORS = 1 << 20;
public PanelComponent()
{
super(0F, 0F, 0F, 0F);
}
public PanelComponent(float x, float y, float width, float height)
{
super(x, y, width, height);
}
@Override
public void init()
{
}
public PanelComponent setScissors(boolean value)
{
setFlag(FLAG_ENABLE_SCISSORS, value);
return this;
}
public boolean isScissoring()
{
return isFlagSet(FLAG_ENABLE_SCISSORS);
}
@Override
public void renderChildren(int mouseX, int mouseY, float particalTicks)
{
if(isFlagSet(FLAG_ENABLE_SCISSORS))
{
enableScissors(getBox());
super.renderChildren(mouseX, mouseY, particalTicks);
disableScissors();
return;
}
super.renderChildren(mouseX, mouseY, particalTicks);
}
}

View File

@ -1,170 +1,176 @@
package speiger.src.coreengine.rendering.gui.components;
import java.util.List;
import java.util.function.Supplier;
import org.lwjgl.opengl.GL11;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
import speiger.src.coreengine.rendering.tesselation.Tesselator;
import speiger.src.coreengine.rendering.tesselation.VertexType;
import speiger.src.coreengine.rendering.utils.GLUtils;
public class PieComponent extends GuiComponent
{
public static final int FLAG_AUTO_UPDATE = 1 << 20;
RenderBuffer buffer;
Supplier<List<IPieIndex>> parts;
int maxSteps;
public PieComponent(int maxSteps, Supplier<List<IPieIndex>> parts)
{
super(0F, 0F, 0F, 0F);
this.maxSteps = maxSteps;
this.parts = parts;
}
public PieComponent(float x, float y, float width, float height, int maxSteps, Supplier<List<IPieIndex>> parts)
{
super(x, y, width, height);
this.maxSteps = maxSteps;
this.parts = parts;
}
@Override
public void init()
{
addCloseListener(buffer = getRenderer().createBuffer());
}
public final PieComponent setAutoUpdate(boolean value)
{
setFlag(FLAG_AUTO_UPDATE, value);
return this;
}
public final boolean isAutoUpdating()
{
return isFlagSet(FLAG_AUTO_UPDATE);
}
public int getMaxSteps()
{
return maxSteps;
}
@Override
protected boolean fixedUpdateSelf()
{
if(isAutoUpdating())
{
createPie();
}
return true;
}
@Override
protected void repaint()
{
createPie();
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float centerX = getBox().getCenterX();
float centerY = getBox().getCenterY();
getRenderer().setBrightness(getActiveBrightness()).translate(centerX, centerY).flush();
GLUtils.DEBTH_TEST.push(true);
getRenderer().drawBuffers(buffer, 0F, 0F).flush();
GLUtils.DEBTH_TEST.pop();
getRenderer().translate(-centerX, -centerY).setBrightness(1F);
return true;
}
protected void createPie()
{
buffer.clear();
if(parts == null)
{
return;
}
float xSize = getBox().getWidth() / 2F;
float ySize = getBox().getHeight() / 2F;
float extra = getBox().getHeight() / 10F;
float value = -3.17F;
float spaceScale = 0.0495F * (127.0F / maxSteps);
List<IPieIndex> indexes = parts.get();
int stepsDone = 0;
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI);
for(int j = indexes.size()-1;j>=0;j--)
{
IPieIndex pieIndex = indexes.get(j);
int steps = j == 0 ? maxSteps - stepsDone : pieIndex.getSteps();
int color = pieIndex.getColor();
int darker = ColorUtils.darker(color);
tes.offset(0F, 0F, 0.01F);
for(int i = 0;i<steps;i++)
{
int index = i + stepsDone;
tes.pos(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(MathUtils.sin(value + spaceScale * index) * xSize, MathUtils.cos(value + spaceScale * index) * ySize * 0.5F, 0F).tex(0F, 0F).color4f(color).endVertex();
index++;
tes.pos(MathUtils.sin(value + spaceScale * index) * xSize, MathUtils.cos(value + spaceScale * index) * ySize * 0.5F, 0F).tex(0F, 0F).color4f(color).endVertex();
}
tes.offset(0F, 0F, -0.01F);
for(int i = 0;i<steps;i++)
{
int index = i + stepsDone;
float x = MathUtils.sin(value + spaceScale * index) * xSize;
float y = MathUtils.cos(value + spaceScale * index) * ySize * 0.5F;
tes.pos(x, y, 0F).tex(0F, 0F).color4f(darker).endVertex();
index++;
float nextX = MathUtils.sin(value + spaceScale * index) * xSize;
float nextY = MathUtils.cos(value + spaceScale * index) * ySize * 0.5F;
tes.pos(nextX, nextY + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(x, y + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(nextX, nextY, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(nextX, nextY + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(x, y, 0F).tex(0F, 0F).color4f(darker).endVertex();
}
stepsDone += steps;
}
buffer.finishShape(0);
}
public static interface IPieIndex
{
public int getSteps();
public int getColor();
}
public static class PieIndex implements IPieIndex
{
int steps;
int color;
public PieIndex(int steps, int color)
{
this.steps = steps;
this.color = color;
}
@Override
public int getSteps()
{
return steps;
}
@Override
public int getColor()
{
return color;
}
}
}
package speiger.src.coreengine.rendering.gui.components;
import java.util.List;
import java.util.function.Supplier;
import org.lwjgl.opengl.GL11;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
import speiger.src.coreengine.rendering.tesselation.Tesselator;
import speiger.src.coreengine.rendering.tesselation.VertexType;
import speiger.src.coreengine.rendering.utils.GLUtils;
import speiger.src.coreengine.utils.profiler.IProfiler.ProfilerData;
public class PieComponent extends GuiComponent
{
public static final int FLAG_AUTO_UPDATE = 1 << 20;
RenderBuffer buffer;
Supplier<List<IPieIndex>> parts;
int maxSteps;
public PieComponent(int maxSteps, Supplier<List<IPieIndex>> parts)
{
super(0F, 0F, 0F, 0F);
this.maxSteps = maxSteps;
this.parts = parts;
}
public PieComponent(float x, float y, float width, float height, int maxSteps, Supplier<List<IPieIndex>> parts)
{
super(x, y, width, height);
this.maxSteps = maxSteps;
this.parts = parts;
}
@Override
public void init()
{
onClose(buffer = getRenderer().createBuffer());
}
public final PieComponent setAutoUpdate(boolean value)
{
setFlag(FLAG_AUTO_UPDATE, value);
return this;
}
public final boolean isAutoUpdating()
{
return isFlagSet(FLAG_AUTO_UPDATE);
}
public int getMaxSteps()
{
return maxSteps;
}
@Override
protected boolean fixedUpdateSelf()
{
if(isAutoUpdating())
{
createPie();
}
return true;
}
@Override
protected void repaint()
{
createPie();
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float centerX = getBox().getCenterX();
float centerY = getBox().getCenterY();
getRenderer().setBrightness(getActiveBrightness()).translate(centerX, centerY).flush();
GLUtils.DEBTH_TEST.push(true);
getRenderer().drawBuffers(buffer, 0F, 0F).flush();
GLUtils.DEBTH_TEST.pop();
getRenderer().translate(-centerX, -centerY).setBrightness(1F);
return true;
}
protected void createPie()
{
buffer.clear();
if(parts == null)
{
return;
}
float xSize = getBox().getWidth() / 2F;
float ySize = getBox().getHeight() / 2F;
float extra = getBox().getHeight() / 10F;
float value = -3.14F;
float spaceScale = 0.0495F * (127.0F / maxSteps);
List<IPieIndex> indexes = parts.get();
int stepsDone = 0;
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI);
for(int j = indexes.size()-1;j>=0;j--)
{
IPieIndex pieIndex = indexes.get(j);
int steps = j == 0 ? maxSteps - stepsDone : pieIndex.getSteps();
int color = pieIndex.getColor();
int darker = ColorUtils.darker(color);
tes.offset(0F, 0F, 0.01F);
for(int i = 0;i<steps;i++)
{
int index = i + stepsDone;
tes.pos(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(MathUtils.sin(value + spaceScale * index) * xSize, MathUtils.cos(value + spaceScale * index) * ySize * 0.5F, 0F).tex(0F, 0F).color4f(color).endVertex();
index++;
tes.pos(MathUtils.sin(value + spaceScale * index) * xSize, MathUtils.cos(value + spaceScale * index) * ySize * 0.5F, 0F).tex(0F, 0F).color4f(color).endVertex();
}
tes.offset(0F, 0F, -0.01F);
for(int i = 0;i<steps;i++)
{
int index = i + stepsDone;
float x = MathUtils.sin(value + spaceScale * index) * xSize;
float y = MathUtils.cos(value + spaceScale * index) * ySize * 0.5F;
tes.pos(x, y, 0F).tex(0F, 0F).color4f(darker).endVertex();
index++;
float nextX = MathUtils.sin(value + spaceScale * index) * xSize;
float nextY = MathUtils.cos(value + spaceScale * index) * ySize * 0.5F;
tes.pos(nextX, nextY + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(x, y + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(nextX, nextY, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(nextX, nextY + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(x, y, 0F).tex(0F, 0F).color4f(darker).endVertex();
}
stepsDone += steps;
}
buffer.finishShape(0);
}
public static interface IPieIndex
{
public int getSteps();
public int getColor();
}
public static class PieIndex implements IPieIndex
{
int steps;
int color;
public PieIndex(ProfilerData data)
{
this(MathUtils.floor(data.getEffect() * 1.28D), data.getColor());
}
public PieIndex(int steps, int color)
{
this.steps = steps;
this.color = color;
}
@Override
public int getSteps()
{
return steps;
}
@Override
public int getColor()
{
return color;
}
}
}

View File

@ -1,122 +1,159 @@
package speiger.src.coreengine.rendering.gui.components;
import java.util.function.IntFunction;
import java.util.function.IntSupplier;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.box.ParentBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
public class ProgressBarComponent extends GuiComponent
{
IGuiBox inner = new ParentBox(1F);
TextComponent text = new TextComponent();
int color;
int value;
int max;
IntFunction<String> name;
IntSupplier valueGenerator;
public ProgressBarComponent(int color, int value, int max)
{
this(color, value, max, null);
}
public ProgressBarComponent(int color, int value, int max, IntFunction<String> name)
{
this(0F, 0F, 0F, 0F, color, value, max, name);
}
public ProgressBarComponent(float x, float y, float width, float height, int color, int value, int max)
{
this(x, y, width, height, color, value, max, null);
}
public ProgressBarComponent(float x, float y, float width, float height, int color, int value, int max, IntFunction<String> name)
{
super(x, y, width, height);
this.name = name;
setColor(color);
setMax(max);
setValue(value);
}
@Override
public void init()
{
addBox(inner);
text.setZOffset(0.1F);
text.setText(stringify());
addChild(text, Constrains.parent());
}
public TextComponent getText()
{
return text;
}
public ProgressBarComponent setColor(int color)
{
this.color = color;
return this;
}
public ProgressBarComponent setValueGenerator(IntSupplier valueGenerator)
{
this.valueGenerator = valueGenerator;
return this;
}
public ProgressBarComponent setValue(int newValue)
{
if(value != newValue)
{
value = newValue;
text.setText(stringify());
}
return this;
}
public ProgressBarComponent setMax(int newMax)
{
if(max != newMax)
{
max = newMax;
if(value > max) setValue(max);
}
return this;
}
protected String stringify()
{
if(name != null) return name.apply(value);
else if(max == 0) return "0%";
return Integer.toString((int)(((float)value / (float)max) * 100F))+"%";
}
protected float getProgress()
{
return max == 0 ? 0F : (float)value / (float)max;
}
@Override
protected boolean fixedUpdateSelf()
{
if(valueGenerator != null) setValue(valueGenerator.getAsInt());
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float extra = (inner.getMaxX() - inner.getMinX()) * getProgress();
UIRenderer render = getRenderer();
render.setBrightness(getActiveBrightness() * 0.75F).drawQuad(getBox(), color);
render.setBrightness(getActiveBrightness()).drawQuad(inner, 0.01F, color);
render.setBrightness(getActiveBrightness() * 1.25F).drawQuad(inner.getMinX(), inner.getMinY(), inner.getMinX() + extra, inner.getMaxY(), 0.02F, color);
text.setBrightness(getActiveBrightness());
return true;
}
}
package speiger.src.coreengine.rendering.gui.components;
import java.util.function.IntFunction;
import java.util.function.IntSupplier;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.box.ParentBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
public class ProgressBarComponent extends GuiComponent
{
IGuiBox inner = new ParentBox(1F);
TextComponent text = new TextComponent();
int color;
int value;
int max;
IntFunction<String> name;
IntSupplier valueGenerator;
public ProgressBarComponent(int color, int value, int max)
{
this(color, value, max, null);
}
public ProgressBarComponent(int color, float textScale, int value, int max)
{
this(color, textScale, value, max, null);
}
public ProgressBarComponent(int color, int value, int max, IntFunction<String> name)
{
this(0F, 0F, 0F, 0F, color, value, max, name);
}
public ProgressBarComponent(int color, float textScale, int value, int max, IntFunction<String> name)
{
this(0F, 0F, 0F, 0F, color, textScale, value, max, name);
}
public ProgressBarComponent(float x, float y, float width, float height, int color, int value, int max)
{
this(x, y, width, height, color, value, max, null);
}
public ProgressBarComponent(float x, float y, float width, float height, int color, float textScale, int value, int max)
{
this(x, y, width, height, color, textScale, value, max, null);
}
public ProgressBarComponent(float x, float y, float width, float height, int color, int value, int max, IntFunction<String> name)
{
this(x, y, width, height, color, 1F, value, max, name);
}
public ProgressBarComponent(float x, float y, float width, float height, int color, float textScale, int value, int max, IntFunction<String> name)
{
super(x, y, width, height);
this.name = name;
text.setTextScale(textScale);
setColor(color);
setMax(max);
setValue(value);
}
@Override
public void init()
{
addBox(inner);
text.setZOffset(0.1F);
text.setText(stringify());
addChild(text, Constrains.parent());
}
public TextComponent getText()
{
return text;
}
public ProgressBarComponent setColor(int color)
{
this.color = color;
return this;
}
public ProgressBarComponent setValueGenerator(IntSupplier valueGenerator)
{
this.valueGenerator = valueGenerator;
return this;
}
public ProgressBarComponent setTextGenerator(IntFunction<String> name)
{
this.name = name;
return this;
}
public ProgressBarComponent setValue(int newValue)
{
if(value != newValue)
{
value = newValue;
text.setText(stringify());
}
return this;
}
public ProgressBarComponent setMax(int newMax)
{
if(max != newMax)
{
max = newMax;
if(value > max) setValue(max);
}
return this;
}
protected String stringify()
{
if(name != null) return name.apply(value);
else if(max == 0) return "0%";
return Integer.toString((int)(((float)value / (float)max) * 100F))+"%";
}
protected float getProgress()
{
return max == 0 ? 0F : (float)value / (float)max;
}
public int getValue()
{
return value;
}
public int getMax()
{
return max;
}
@Override
protected boolean fixedUpdateSelf()
{
if(valueGenerator != null) setValue(valueGenerator.getAsInt());
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float extra = (inner.getMaxX() - inner.getMinX()) * getProgress();
UIRenderer render = getRenderer();
render.setBrightness(getActiveBrightness() * 0.75F).drawQuad(getBox(), color);
render.setBrightness(getActiveBrightness()).drawQuad(inner, 0.01F, color);
render.setBrightness(getActiveBrightness() * 1.25F).drawQuad(inner.getMinX(), inner.getMinY(), inner.getMinX() + extra, inner.getMaxY(), 0.02F, color);
text.setBrightness(getActiveBrightness());
return true;
}
}

View File

@ -1,243 +1,243 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
public class ScrollBarComponent extends GuiComponent implements IButtonComponent
{
public static final int FLAG_HORIZONTAL = 1024;
public static final int FLAG_INVERTED = 2048;
int color;
float lastMouse = -1;
int current;
int max;
public ScrollBarComponent(int color)
{
super(0F, 0F, 0F, 0F);
this.color = color;
}
public ScrollBarComponent(int color, int max)
{
super(0F, 0F, 0F, 0F);
this.color = color;
this.max = max;
}
public ScrollBarComponent(int color, int max, int current)
{
super(0F, 0F, 0F, 0F);
this.color = color;
this.max = max;
this.current = current;
}
public ScrollBarComponent(float x, float y, float width, float height, int color)
{
super(x, y, width, height);
this.color = color;
}
public ScrollBarComponent(float x, float y, float width, float height, int color, int max)
{
super(x, y, width, height);
this.color = color;
this.max = max;
}
public ScrollBarComponent(float x, float y, float width, float height, int color, int max, int current)
{
super(x, y, width, height);
this.color = color;
this.max = max;
this.current = current;
}
@Override
public void init()
{
}
public ScrollBarComponent setColor(int color)
{
this.color = color;
return this;
}
public ScrollBarComponent setScrollMax(int max)
{
this.max = max;
return addScroll(0);
}
public ScrollBarComponent addScroll(int add)
{
return setScrollCurrent(current + add);
}
public ScrollBarComponent setScrollEnd()
{
return setScrollCurrent(max);
}
public ScrollBarComponent setScrollStart()
{
return setScrollCurrent(0);
}
public ScrollBarComponent setScrollCurrent(int current)
{
this.current = (int)MathUtils.clamp(0F, Math.max(0, max - getBaseRange()), current);
return this;
}
protected int getCurrent()
{
return current;
}
protected void setCurrent(int value)
{
current = value;
}
public ScrollBarComponent setHorizontal(boolean value)
{
setFlag(FLAG_HORIZONTAL, value);
return this;
}
public ScrollBarComponent setInverted(boolean value)
{
setFlag(FLAG_INVERTED, value);
return this;
}
public boolean isHorizontal()
{
return isFlagSet(FLAG_HORIZONTAL);
}
public int getScroll()
{
return current;
}
public boolean isAtEnd()
{
return (max - getBaseRange()) <= current;
}
public boolean isInUse()
{
return (max - getBaseRange()) > 0F;
}
public float getRequiredSpace()
{
return (max - getBaseRange()) > 0F ? (isHorizontal() ? getBox().getHeight() : getBox().getWidth()) : 0F;
}
@Override
public boolean isComponentColliding(int mouseX, int mouseY)
{
return isInUse() && isHovered(mouseX, mouseY);
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float baseRange = getBaseRange();
float extra = max - baseRange;
if(extra <= 0)
{
return true;
}
IGuiBox box = getBox();
float range = getRange();
float min = getCurrent() * (baseRange - range) / extra;
float brightness = getActiveBrightness();
getRenderer().setBrightness(brightness * 0.5F).drawQuad(box, color);
if(isHorizontal()) getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(min), box.getMinY(), box.getMinX(min + range), box.getMaxY(), 0.01F, color);
else getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(), box.getMinY(min), box.getMaxX(), box.getMinY(min + range), 0.01F, color);
getRenderer().setBrightness(1F);
return true;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
float baseRange = getBaseRange();
float extra = max - baseRange;
if(extra <= 0F)
{
return false;
}
float range = getRange();
float pos = (baseRange - range) / extra;
float start = Math.max(0F, getCurrent() * pos);
IGuiBox box = getBox();
float currentPos = (isHorizontal() ? box.getMinX(start) : box.getMinY(start)) + ((range * box.getScale()) / 2F);
float mouse = isHorizontal() ? mouseX : mouseY;
if(mouse < currentPos)
{
setCurrent((int)Math.max(0F, getCurrent() - (((currentPos - mouse) / pos) / box.getScale())));
}
else if(mouse > currentPos)
{
setCurrent((int)Math.min(extra, getCurrent() + (((mouse - currentPos) / pos) / box.getScale())));
}
lastMouse = mouse;
return true;
}
@Override
public boolean onDrag(int mouseX, int mouseY)
{
if(lastMouse != -1F)
{
float range = getRange();
IGuiBox box = getBox();
float mouse = (isHorizontal() ? mouseX - box.getMinX() : mouseY - box.getMinY()) - ((range * box.getScale()) / 2F);
float baseRange = getBaseRange();
float extra = max - baseRange;
setCurrent((int)MathUtils.clamp(0F, Math.max(0F, extra), (mouse / ((baseRange - range) / extra)) / box.getScale()));
return true;
}
return false;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
lastMouse = -1F;
}
@Override
public boolean onScroll(int scroll, int mouseX, int mouseY)
{
float extra = max - getBaseRange();
if(extra > 0F)
{
setCurrent((int)MathUtils.clamp(0, extra, current - (scroll * (extra / 10F))));
return true;
}
return false;
}
protected float getBaseRange()
{
return isHorizontal() ? getBox().getBaseWidth() : getBox().getBaseHeight();
}
protected float getRange()
{
float value = getBaseRange();
return MathUtils.clamp(10F, value, ((value * value) / max));
}
}
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
public class ScrollBarComponent extends GuiComponent implements IButtonComponent
{
public static final int FLAG_HORIZONTAL = 1 << 20;
public static final int FLAG_INVERTED = 1 << 21;
int color;
float lastMouse = -1;
int current;
int max;
public ScrollBarComponent(int color)
{
super(0F, 0F, 0F, 0F);
this.color = color;
}
public ScrollBarComponent(int color, int max)
{
super(0F, 0F, 0F, 0F);
this.color = color;
this.max = max;
}
public ScrollBarComponent(int color, int max, int current)
{
super(0F, 0F, 0F, 0F);
this.color = color;
this.max = max;
this.current = current;
}
public ScrollBarComponent(float x, float y, float width, float height, int color)
{
super(x, y, width, height);
this.color = color;
}
public ScrollBarComponent(float x, float y, float width, float height, int color, int max)
{
super(x, y, width, height);
this.color = color;
this.max = max;
}
public ScrollBarComponent(float x, float y, float width, float height, int color, int max, int current)
{
super(x, y, width, height);
this.color = color;
this.max = max;
this.current = current;
}
@Override
public void init()
{
}
public ScrollBarComponent setColor(int color)
{
this.color = color;
return this;
}
public ScrollBarComponent setScrollMax(int max)
{
this.max = max;
return addScroll(0);
}
public ScrollBarComponent addScroll(int add)
{
return setScrollCurrent(current + add);
}
public ScrollBarComponent setScrollEnd()
{
return setScrollCurrent(max);
}
public ScrollBarComponent setScrollStart()
{
return setScrollCurrent(0);
}
public ScrollBarComponent setScrollCurrent(int current)
{
this.current = (int)MathUtils.clamp(0F, Math.max(0, max - getBaseRange()), current);
return this;
}
protected int getCurrent()
{
return current;
}
protected void setCurrent(int value)
{
current = value;
}
public ScrollBarComponent setHorizontal(boolean value)
{
setFlag(FLAG_HORIZONTAL, value);
return this;
}
public ScrollBarComponent setInverted(boolean value)
{
setFlag(FLAG_INVERTED, value);
return this;
}
public boolean isHorizontal()
{
return isFlagSet(FLAG_HORIZONTAL);
}
public int getScroll()
{
return current;
}
public boolean isAtEnd()
{
return (max - getBaseRange()) <= current;
}
public boolean isInUse()
{
return (max - getBaseRange()) > 0F;
}
public float getRequiredSpace()
{
return (max - getBaseRange()) > 0F ? (isHorizontal() ? getBox().getHeight() : getBox().getWidth()) : 0F;
}
@Override
public boolean isComponentColliding(int mouseX, int mouseY)
{
return isInUse() && isHovered(mouseX, mouseY);
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float baseRange = getBaseRange();
float extra = max - baseRange;
if(extra <= 0)
{
return true;
}
IGuiBox box = getBox();
float range = getRange();
float min = getCurrent() * (baseRange - range) / extra;
float brightness = getActiveBrightness();
getRenderer().setBrightness(brightness * 0.5F).drawQuad(box, color);
if(isHorizontal()) getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(min), box.getMinY(), box.getMinX(min + range), box.getMaxY(), 0.01F, color);
else getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(), box.getMinY(min), box.getMaxX(), box.getMinY(min + range), 0.01F, color);
getRenderer().setBrightness(1F);
return true;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
float baseRange = getBaseRange();
float extra = max - baseRange;
if(extra <= 0F)
{
return false;
}
float range = getRange();
float pos = (baseRange - range) / extra;
float start = Math.max(0F, getCurrent() * pos);
IGuiBox box = getBox();
float currentPos = (isHorizontal() ? box.getMinX(start) : box.getMinY(start)) + ((range * box.getScale()) / 2F);
float mouse = isHorizontal() ? mouseX : mouseY;
if(mouse < currentPos)
{
setCurrent((int)Math.max(0F, getCurrent() - (((currentPos - mouse) / pos) / box.getScale())));
}
else if(mouse > currentPos)
{
setCurrent((int)Math.min(extra, getCurrent() + (((mouse - currentPos) / pos) / box.getScale())));
}
lastMouse = mouse;
return true;
}
@Override
public boolean onDrag(int mouseX, int mouseY)
{
if(lastMouse != -1F)
{
float range = getRange();
IGuiBox box = getBox();
float mouse = (isHorizontal() ? mouseX - box.getMinX() : mouseY - box.getMinY()) - ((range * box.getScale()) / 2F);
float baseRange = getBaseRange();
float extra = max - baseRange;
setCurrent((int)MathUtils.clamp(0F, Math.max(0F, extra), (mouse / ((baseRange - range) / extra)) / box.getScale()));
return true;
}
return false;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
lastMouse = -1F;
}
@Override
public boolean onScroll(int scroll, int mouseX, int mouseY)
{
float extra = max - getBaseRange();
if(extra > 0F)
{
setCurrent((int)MathUtils.clamp(0, extra, current - (scroll * (extra / 10F))));
return true;
}
return false;
}
protected float getBaseRange()
{
return isHorizontal() ? getBox().getBaseWidth() : getBox().getBaseHeight();
}
protected float getRange()
{
float value = getBaseRange();
return MathUtils.clamp(10F, value, ((value * value) / max));
}
}

View File

@ -1,96 +1,96 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.ConditionalConstraint;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
public class ScrollPanelComponent extends GuiComponent
{
public static final int FLAG_CORNER = 1 << 20;
ScrollBarComponent horizontalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY).setHorizontal(true);
ScrollBarComponent verticalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY);
protected PanelComponent container = new PanelComponent().setManualRenderer(true).setScissorsTest(true).cast();
PanelComponent viewPort = new PanelComponent().setManualRenderer(true).cast();
public ScrollPanelComponent()
{
super(0F, 0F, 0F, 0F);
}
public ScrollPanelComponent(float x, float y, float width, float height)
{
super(x, y, width, height);
}
@Override
public void init()
{
addChild(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
addChild(verticalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, false, 5F));
viewPort.addChild(container);
container.addChangeListener(this::recalculateSize);
addChild(viewPort, Constrains.width(ConditionalConstraint.parent(verticalBar::isInUse, 0F, 5F)).height(ConditionalConstraint.parent(horizontalBar::isInUse, 0F, 5F)).build());
}
public ScrollPanelComponent setForcedCorner(boolean value)
{
if(setFlag(FLAG_CORNER, value) && getGui() != null)
{
addConstrains(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
addConstrains(verticalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, false, 5F));
onChanged(false);
}
return this;
}
public PanelComponent getContainer()
{
return container;
}
public PanelComponent getViewPort()
{
return viewPort;
}
protected void recalculateSize(GuiComponent owner)
{
float maxX = 0F;
float maxY = 0F;
for(GuiComponent component : container.getChildren())
{
IGuiBox box = component.getBox();
maxX = Math.max(maxX, box.getBaseX() + box.getBaseWidth());
maxY = Math.max(maxY, box.getBaseY() + box.getBaseHeight());
}
horizontalBar.setScrollMax((int)maxX);
verticalBar.setScrollMax((int)maxY);
owner.bounds(maxX, maxY).set(-horizontalBar.getScroll(), -verticalBar.getScroll());
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
super.updateSelf(mouseX, mouseY, particalTicks);
container.set(-horizontalBar.getScroll(), -verticalBar.getScroll());
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
renderChildren(mouseX, mouseY, particalTicks);
if(container.isVisible())
{
enableScissors(viewPort.getBox());
getRenderer().translate(0F, 0F, 0.1F);
container.render(mouseX, mouseY, particalTicks);
getRenderer().translate(0F, 0F, -0.1F);
disableScissors();
}
return false;
}
}
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.ConditionalConstraint;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
public class ScrollPanelComponent extends GuiComponent
{
public static final int FLAG_CORNER = 1 << 20;
ScrollBarComponent horizontalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY).setHorizontal(true);
ScrollBarComponent verticalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY);
protected PanelComponent container = new PanelComponent().setManualRenderer(true).setScissorsTest(true).cast();
PanelComponent viewPort = new PanelComponent().setManualRenderer(true).cast();
public ScrollPanelComponent()
{
super(0F, 0F, 0F, 0F);
}
public ScrollPanelComponent(float x, float y, float width, float height)
{
super(x, y, width, height);
}
@Override
public void init()
{
addChild(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
addChild(verticalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, false, 5F));
viewPort.addChild(container);
container.onChange(this::recalculateSize);
addChild(viewPort, Constrains.width(ConditionalConstraint.parent(verticalBar::isInUse, 0F, 5F)).height(ConditionalConstraint.parent(horizontalBar::isInUse, 0F, 5F)).build());
}
public ScrollPanelComponent setForcedCorner(boolean value)
{
if(setFlag(FLAG_CORNER, value) && getGui() != null)
{
addConstrains(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
addConstrains(verticalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, false, 5F));
onChanged(false);
}
return this;
}
public PanelComponent getContainer()
{
return container;
}
public PanelComponent getViewPort()
{
return viewPort;
}
protected void recalculateSize(GuiComponent owner)
{
float maxX = 0F;
float maxY = 0F;
for(GuiComponent component : container.getChildren())
{
IGuiBox box = component.getBox();
maxX = Math.max(maxX, box.getBaseX() + box.getBaseWidth());
maxY = Math.max(maxY, box.getBaseY() + box.getBaseHeight());
}
horizontalBar.setScrollMax((int)maxX);
verticalBar.setScrollMax((int)maxY);
owner.bounds(maxX, maxY).set(-horizontalBar.getScroll(), -verticalBar.getScroll());
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
super.updateSelf(mouseX, mouseY, particalTicks);
container.set(-horizontalBar.getScroll(), -verticalBar.getScroll());
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
renderChildren(mouseX, mouseY, particalTicks);
if(container.isVisible())
{
enableScissors(viewPort.getBox());
getRenderer().translate(0F, 0F, 0.1F);
container.render(mouseX, mouseY, particalTicks);
getRenderer().translate(0F, 0F, -0.1F);
disableScissors();
}
return false;
}
}

View File

@ -1,109 +1,109 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.ConditionalConstraint;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
public class ScrollWindowComponent extends WindowComponent
{
public static final int FLAG_CORNER = 1 << 26;
ScrollBarComponent horizontalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY).setHorizontal(true);
ScrollBarComponent verticalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY);
protected PanelComponent container = new PanelComponent().setManualRenderer(true).cast();
PanelComponent viewPort = new PanelComponent().setManualRenderer(true).cast();
public ScrollWindowComponent(int flags, String name)
{
super(0F, 0F, 0F, 0F, flags, name);
}
public ScrollWindowComponent(float x, float y, float width, float height, int flags, String name)
{
super(x, y, width, height, flags, name);
}
@Override
public void init()
{
super.init();
addChild(horizontalBar.addChangeListener(minimizedListener), Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
addChild(verticalBar.addChangeListener(minimizedListener), Constrains.verticalScrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, 7.5F, 5F));
viewPort.addChild(container);
container.addChangeListener(this::recalculateSize).addChangeListener(minimizedListener);
addChild(viewPort.set(0F, 7.5F), Constrains.width(ConditionalConstraint.parent(verticalBar::isInUse, 0F, 5F)).height(ConditionalConstraint.parent(horizontalBar::isInUse, 0F, 5F)).build());
}
public <T extends GuiComponent> T addComponent(T comp)
{
return container.addChild(comp);
}
public <T extends GuiComponent> T addComponent(T comp, Constrains constraints)
{
return container.addChild(comp, constraints);
}
public PanelComponent getContainer()
{
return container;
}
public PanelComponent getViewPort()
{
return viewPort;
}
public ScrollWindowComponent setForcedCorner(boolean value)
{
if(setFlag(FLAG_CORNER, value) && getGui() != null)
{
addConstrains(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
addConstrains(verticalBar, Constrains.verticalScrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, 7.5F, 5F));
onChanged(false);
}
return this;
}
protected void recalculateSize(GuiComponent owner)
{
float maxX = 0F;
float maxY = 0F;
for(GuiComponent component : container.getChildren())
{
IGuiBox box = component.getBox();
maxX = Math.max(maxX, box.getBaseX() + box.getBaseWidth());
maxY = Math.max(maxY, box.getBaseY() + box.getBaseHeight());
}
horizontalBar.setScrollMax((int)maxX);
verticalBar.setScrollMax((int)maxY);
horizontalBar.onChanged(true);
verticalBar.onChanged(true);
owner.bounds(maxX, maxY).set(-horizontalBar.getScroll(), -verticalBar.getScroll());
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
super.updateSelf(mouseX, mouseY, particalTicks);
container.set(-horizontalBar.getScroll(), -verticalBar.getScroll());
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
super.renderSelf(mouseX, mouseY, particalTicks);
renderChildren(mouseX, mouseY, particalTicks);
if(container.isVisible())
{
enableScissors(viewPort.getBox());
getRenderer().translate(0F, 0F, 0.1F);
container.render(mouseX, mouseY, particalTicks);
getRenderer().translate(0F, 0F, -0.1F);
disableScissors();
}
return false;
}
}
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.ConditionalConstraint;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
public class ScrollWindowComponent extends WindowComponent
{
public static final int FLAG_CORNER = 1 << 26;
ScrollBarComponent horizontalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY).setHorizontal(true);
ScrollBarComponent verticalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY);
protected PanelComponent container = new PanelComponent().setManualRenderer(true).cast();
PanelComponent viewPort = new PanelComponent().setManualRenderer(true).cast();
public ScrollWindowComponent(int flags, String name)
{
super(0F, 0F, 0F, 0F, flags, name);
}
public ScrollWindowComponent(float x, float y, float width, float height, int flags, String name)
{
super(x, y, width, height, flags, name);
}
@Override
public void init()
{
super.init();
addChild(horizontalBar.onChange(minimizedListener), Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
addChild(verticalBar.onChange(minimizedListener), Constrains.verticalScrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, 7.5F, 5F));
viewPort.addChild(container);
container.onChange(this::recalculateSize).onChange(minimizedListener);
addChild(viewPort.set(0F, 7.5F), Constrains.width(ConditionalConstraint.parent(verticalBar::isInUse, 0F, 5F)).height(ConditionalConstraint.parent(horizontalBar::isInUse, 0F, 5F)).build());
}
public <T extends GuiComponent> T addComponent(T comp)
{
return container.addChild(comp);
}
public <T extends GuiComponent> T addComponent(T comp, Constrains constraints)
{
return container.addChild(comp, constraints);
}
public PanelComponent getContainer()
{
return container;
}
public PanelComponent getViewPort()
{
return viewPort;
}
public ScrollWindowComponent setForcedCorner(boolean value)
{
if(setFlag(FLAG_CORNER, value) && getGui() != null)
{
addConstrains(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
addConstrains(verticalBar, Constrains.verticalScrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, 7.5F, 5F));
onChanged(false);
}
return this;
}
protected void recalculateSize(GuiComponent owner)
{
float maxX = 0F;
float maxY = 0F;
for(GuiComponent component : container.getChildren())
{
IGuiBox box = component.getBox();
maxX = Math.max(maxX, box.getBaseX() + box.getBaseWidth());
maxY = Math.max(maxY, box.getBaseY() + box.getBaseHeight());
}
horizontalBar.setScrollMax((int)maxX);
verticalBar.setScrollMax((int)maxY);
horizontalBar.onChanged(true);
verticalBar.onChanged(true);
owner.bounds(maxX, maxY).set(-horizontalBar.getScroll(), -verticalBar.getScroll());
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
super.updateSelf(mouseX, mouseY, particalTicks);
container.set(-horizontalBar.getScroll(), -verticalBar.getScroll());
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
super.renderSelf(mouseX, mouseY, particalTicks);
renderChildren(mouseX, mouseY, particalTicks);
if(container.isVisible())
{
enableScissors(viewPort.getBox());
getRenderer().translate(0F, 0F, 0.1F);
container.render(mouseX, mouseY, particalTicks);
getRenderer().translate(0F, 0F, -0.1F);
disableScissors();
}
return false;
}
}

View File

@ -1,363 +1,363 @@
package speiger.src.coreengine.rendering.gui.components;
import java.util.Collection;
import java.util.function.Consumer;
import org.lwjgl.opengl.GL11;
import speiger.src.collections.ints.collections.IntCollection;
import speiger.src.coreengine.math.value.IValue;
import speiger.src.coreengine.math.value.LiniarValue;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.components.list.SelectionEntry;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
import speiger.src.coreengine.rendering.tesselation.Tesselator;
import speiger.src.coreengine.rendering.tesselation.VertexType;
public class SelectionComponent extends GuiComponent implements IButtonComponent, Consumer<GuiComponent>
{
public static final int FLAG_ANIMATE = 1 << 20;
ListComponent<SelectionEntry> list = new ListComponent<SelectionEntry>().bounds(0F, 120F).setManualRenderer(true).setIgnoreBounds(true).cast();
TextComponent text = new TextComponent().align(Align.LEFT_TOP, Align.CENTER).setTextScale(0.85F).setManualRenderer(true).cast();
RenderBuffer buffer;
int color;
boolean isOpen = false;
int selectedIndex = -1;
int defaultIndex = -1;
IValue animation = null;
public SelectionComponent(int color)
{
super(0F, 0F, 0F, 0F);
this.color = color;
text.setText("Select Index");
list.setColor(color);
}
public SelectionComponent(int color, Collection<String> collection)
{
super(0F, 0F, 0F, 0F);
this.color = color;
text.setText("Select Index");
list.setColor(color);
addEntries(collection);
}
public SelectionComponent(float x, float y, float width, float height, int color)
{
super(x, y, width, height);
this.color = color;
text.setText("Select Index");
list.setColor(color);
}
public SelectionComponent(float x, float y, float width, float height, int color, Collection<String> collection)
{
super(x, y, width, height);
this.color = color;
text.setText("Select Index");
list.setColor(color);
addEntries(collection);
}
@Override
public void init()
{
list.setEntryHeight(getGui().getFont().height()).addUserActionListener(this);
addChild(text, Constrains.parent(21F, 0F, 10.5F, 0F));
addChild(list, Constrains.parent(Target.X).invParent(Target.Y).parent(Target.WIDTH).build());
addCloseListener(buffer = getRenderer().createBuffer());
createArrow();
}
public final SelectionComponent setAnimating(boolean value)
{
setFlag(FLAG_ANIMATE, value);
return this;
}
public final boolean isAnimating()
{
return isFlagSet(FLAG_ANIMATE);
}
@Override
protected void updateState()
{
list.setVisible(isOpen);
}
public TextComponent getText()
{
return text;
}
public ListComponent<SelectionEntry> getList()
{
return list;
}
public SelectionComponent addEntry(String s)
{
list.add(new SelectionEntry(s));
return this;
}
public SelectionComponent addEntries(Collection<String> collection)
{
for(String s : collection)
{
list.add(new SelectionEntry(s));
}
return this;
}
public SelectionComponent updateEntry(int index, String newName)
{
list.get(index).setText(newName);
if(index == selectedIndex)
{
updateSelection();
}
return this;
}
public SelectionComponent removeEntry(String s)
{
for(int i = 0,m=list.size();i<m;i++)
{
if(list.get(i).getText().equals(s))
{
list.remove(i);
if(selectedIndex == i)
{
updateSelection();
}
return this;
}
}
return this;
}
public SelectionComponent removeIndex(int index)
{
if(list.remove(index) != null && selectedIndex == index)
{
updateSelection();
}
return this;
}
public SelectionComponent removeIndexes(IntCollection values)
{
if(list.removeAll(values) && values.contains(selectedIndex))
{
updateSelection();
}
return this;
}
public SelectionComponent setDefaultIndex(int index)
{
defaultIndex = index;
if(index != -1 && selectedIndex == -1)
{
list.setSelectedIndex(index);
updateSelection();
}
return this;
}
public SelectionComponent setSelectedIndex(int index)
{
list.setSelectedIndex(index);
updateSelection();
return this;
}
public int getSelectedIndex()
{
return selectedIndex;
}
public String getSelectedValue()
{
return list.get(selectedIndex).getText();
}
protected void createArrow()
{
if(buffer == null)
{
return;
}
buffer.clear();
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI).setOffset(-6F, -6F, 0F);
tes.pos(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(0F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(0F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(12F, 6F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.setOffset(0F, 0F, 0F);
buffer.finishShape(0);
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
if(animation != null)
{
animation.update(particalTicks);
if(animation.isDone())
{
if(animation.get() < 1F)
{
isOpen = false;
list.setVisible(false);
}
animation = null;
}
}
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brightness = getActiveBrightness();
IGuiBox box = getBox();
float minX = box.getMinX(10F);
float minY = box.getMinY(10F);
float currentZ = getRenderer().getCurrentZ();
float rotation = animation != null ? animation.get() : (isOpen ? 90 : 0);
UIRenderer render = getRenderer();
render.setBrightness(brightness).drawQuad(box, color);
render.setBrightness(brightness * 0.7F).drawQuad(box.getMinX(), box.getMinY(), box.getMinX(20F), box.getMaxY(), 0.001F, color);
render.setFastTransform(false).setBrightness(brightness).translate(minX, minY, 0.02F + currentZ);
render.scale(box.getScale()).rotateZ(rotation).drawBuffers(buffer, 0, 0).resetTransform().setFastTransform(true).translate(0F, 0F, 0.01F).setBrightness(1F);
text.render(mouseX, mouseY, particalTicks);
if(animation != null)
{
float progress = animation.get() / 90F;
box = list.getBox();
enableScissors(box.getMinX(), box.getMinY(), box.getWidth(), box.getHeight() * progress);
list.render(mouseX, mouseY, particalTicks);
disableScissors();
}
else if(isOpen)
{
list.render(mouseX, mouseY, particalTicks);
}
return true;
}
@Override
public boolean isComponentColliding(int mouseX, int mouseY)
{
return isMouseOver(mouseX, mouseY) || (isOpen && list.isComponentColliding(mouseX, mouseY));
}
@Override
public boolean isValidButton(int button)
{
return button == 0 || button == 2;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
//TODO look how to move into OnRelease
if(isOpen && button == 0)
{
if(isMouseOver(mouseX, mouseY) && animation == null)
{
close();
}
return animation == null && list.onClick(button, mouseX, mouseY);
}
if(button == 2)
{
list.setSelectedIndex(-1);
updateSelection();
return true;
}
isOpen = true;
list.setVisible(true);
if(isAnimating())
{
animation = new LiniarValue(2F, 0F, 90F).setSmooth();
}
return true;
}
@Override
public boolean onDrag(int mouseX, int mouseY)
{
return isOpen && animation == null && list.onDrag(mouseX, mouseY);
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
if(isOpen && animation == null)
{
list.onRelease(button, mouseX, mouseY);
}
}
@Override
public boolean onScroll(int scroll, int mouseX, int mouseY)
{
return isOpen && animation == null && list.onScroll(scroll, mouseX, mouseY);
}
protected void close()
{
if(isAnimating())
{
animation = new LiniarValue(2F, 90F, 0F).setSmooth();
}
else
{
isOpen = false;
list.setVisible(false);
}
}
@Override
public void accept(GuiComponent t)
{
updateSelection();
close();
}
protected void updateSelection()
{
if(list.hasSelected())
{
selectedIndex = list.getSelectedIndex();
text.setText(list.get(selectedIndex).getText());
}
else if(defaultIndex != -1)
{
list.setSelectedIndex(defaultIndex);
selectedIndex = list.getSelectedIndex();
text.setText(list.get(selectedIndex).getText());
}
else
{
selectedIndex = -1;
text.setText("Select Index");
}
}
}
package speiger.src.coreengine.rendering.gui.components;
import java.util.Collection;
import java.util.function.Consumer;
import org.lwjgl.opengl.GL11;
import speiger.src.collections.ints.collections.IntCollection;
import speiger.src.coreengine.math.value.IValue;
import speiger.src.coreengine.math.value.LiniarValue;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.components.list.SelectionEntry;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
import speiger.src.coreengine.rendering.tesselation.Tesselator;
import speiger.src.coreengine.rendering.tesselation.VertexType;
public class SelectionComponent extends GuiComponent implements IButtonComponent, Consumer<GuiComponent>
{
public static final int FLAG_ANIMATE = 1 << 20;
ListComponent<SelectionEntry> list = new ListComponent<SelectionEntry>().bounds(0F, 120F).setManualRenderer(true).setIgnoreBounds(true).cast();
TextComponent text = new TextComponent().align(Align.LEFT_TOP, Align.CENTER).setTextScale(0.85F).setManualRenderer(true).cast();
RenderBuffer buffer;
int color;
boolean isOpen = false;
int selectedIndex = -1;
int defaultIndex = -1;
IValue animation = null;
public SelectionComponent(int color)
{
super(0F, 0F, 0F, 0F);
this.color = color;
text.setText("Select Index");
list.setColor(color);
}
public SelectionComponent(int color, Collection<String> collection)
{
super(0F, 0F, 0F, 0F);
this.color = color;
text.setText("Select Index");
list.setColor(color);
addEntries(collection);
}
public SelectionComponent(float x, float y, float width, float height, int color)
{
super(x, y, width, height);
this.color = color;
text.setText("Select Index");
list.setColor(color);
}
public SelectionComponent(float x, float y, float width, float height, int color, Collection<String> collection)
{
super(x, y, width, height);
this.color = color;
text.setText("Select Index");
list.setColor(color);
addEntries(collection);
}
@Override
public void init()
{
list.setEntryHeight(getGui().getFont().height()).onAction(this);
addChild(text, Constrains.parent(21F, 0F, 10.5F, 0F));
addChild(list, Constrains.parent(Target.X).invParent(Target.Y).parent(Target.WIDTH).build());
onClose(buffer = getRenderer().createBuffer());
createArrow();
}
public final SelectionComponent setAnimating(boolean value)
{
setFlag(FLAG_ANIMATE, value);
return this;
}
public final boolean isAnimating()
{
return isFlagSet(FLAG_ANIMATE);
}
@Override
protected void updateState()
{
list.setVisible(isOpen);
}
public TextComponent getText()
{
return text;
}
public ListComponent<SelectionEntry> getList()
{
return list;
}
public SelectionComponent addEntry(String s)
{
list.add(new SelectionEntry(s));
return this;
}
public SelectionComponent addEntries(Collection<String> collection)
{
for(String s : collection)
{
list.add(new SelectionEntry(s));
}
return this;
}
public SelectionComponent updateEntry(int index, String newName)
{
list.get(index).setText(newName);
if(index == selectedIndex)
{
updateSelection();
}
return this;
}
public SelectionComponent removeEntry(String s)
{
for(int i = 0,m=list.size();i<m;i++)
{
if(list.get(i).getText().equals(s))
{
list.remove(i);
if(selectedIndex == i)
{
updateSelection();
}
return this;
}
}
return this;
}
public SelectionComponent removeIndex(int index)
{
if(list.remove(index) != null && selectedIndex == index)
{
updateSelection();
}
return this;
}
public SelectionComponent removeIndexes(IntCollection values)
{
if(list.removeAll(values) && values.contains(selectedIndex))
{
updateSelection();
}
return this;
}
public SelectionComponent setDefaultIndex(int index)
{
defaultIndex = index;
if(index != -1 && selectedIndex == -1)
{
list.setSelectedIndex(index);
updateSelection();
}
return this;
}
public SelectionComponent setSelectedIndex(int index)
{
list.setSelectedIndex(index);
updateSelection();
return this;
}
public int getSelectedIndex()
{
return selectedIndex;
}
public String getSelectedValue()
{
return list.get(selectedIndex).getText();
}
protected void createArrow()
{
if(buffer == null)
{
return;
}
buffer.clear();
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI).setOffset(-6F, -6F, 0F);
tes.pos(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(0F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(0F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(12F, 6F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.setOffset(0F, 0F, 0F);
buffer.finishShape(0);
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
if(animation != null)
{
animation.update(particalTicks);
if(animation.isDone())
{
if(animation.get() < 1F)
{
isOpen = false;
list.setVisible(false);
}
animation = null;
}
}
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brightness = getActiveBrightness();
IGuiBox box = getBox();
float minX = box.getMinX(10F);
float minY = box.getMinY(10F);
float currentZ = getRenderer().getCurrentZ();
float rotation = animation != null ? animation.get() : (isOpen ? 90 : 0);
UIRenderer render = getRenderer();
render.setBrightness(brightness).drawQuad(box, color);
render.setBrightness(brightness * 0.7F).drawQuad(box.getMinX(), box.getMinY(), box.getMinX(20F), box.getMaxY(), 0.001F, color);
render.setFastTransform(false).setBrightness(brightness).translate(minX, minY, 0.02F + currentZ);
render.scale(box.getScale()).rotateZ(rotation).drawBuffers(buffer, 0, 0).resetTransform().setFastTransform(true).translate(0F, 0F, 0.01F).setBrightness(1F);
text.render(mouseX, mouseY, particalTicks);
if(animation != null)
{
float progress = animation.get() / 90F;
box = list.getBox();
enableScissors(box.getMinX(), box.getMinY(), box.getWidth(), box.getHeight() * progress);
list.render(mouseX, mouseY, particalTicks);
disableScissors();
}
else if(isOpen)
{
list.render(mouseX, mouseY, particalTicks);
}
return true;
}
@Override
public boolean isComponentColliding(int mouseX, int mouseY)
{
return isMouseOver(mouseX, mouseY) || (isOpen && list.isComponentColliding(mouseX, mouseY));
}
@Override
public boolean isValidButton(int button)
{
return button == 0 || button == 2;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
//TODO look how to move into OnRelease
if(isOpen && button == 0)
{
if(isMouseOver(mouseX, mouseY) && animation == null)
{
close();
}
return animation == null && list.onClick(button, mouseX, mouseY);
}
if(button == 2)
{
list.setSelectedIndex(-1);
updateSelection();
return true;
}
isOpen = true;
list.setVisible(true);
if(isAnimating())
{
animation = new LiniarValue(2F, 0F, 90F).setSmooth();
}
return true;
}
@Override
public boolean onDrag(int mouseX, int mouseY)
{
return isOpen && animation == null && list.onDrag(mouseX, mouseY);
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
if(isOpen && animation == null)
{
list.onRelease(button, mouseX, mouseY);
}
}
@Override
public boolean onScroll(int scroll, int mouseX, int mouseY)
{
return isOpen && animation == null && list.onScroll(scroll, mouseX, mouseY);
}
protected void close()
{
if(isAnimating())
{
animation = new LiniarValue(2F, 90F, 0F).setSmooth();
}
else
{
isOpen = false;
list.setVisible(false);
}
}
@Override
public void accept(GuiComponent t)
{
updateSelection();
close();
}
protected void updateSelection()
{
if(list.hasSelected())
{
selectedIndex = list.getSelectedIndex();
text.setText(list.get(selectedIndex).getText());
}
else if(defaultIndex != -1)
{
list.setSelectedIndex(defaultIndex);
selectedIndex = list.getSelectedIndex();
text.setText(list.get(selectedIndex).getText());
}
else
{
selectedIndex = -1;
text.setText("Select Index");
}
}
}

View File

@ -0,0 +1,334 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.collections.objects.functions.function.Object2FloatFunction;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
import speiger.src.coreengine.utils.functions.FloatSupplier;
public class SingleTabPanelComponent extends PanelComponent
{
PanelComponent selection = new PanelComponent();
PanelComponent panel = new PanelComponent().setScissors(true);
ObjectList<Tab> tabs = new ObjectArrayList<>();
int selectedTab = -1;
float tabScale = 1F;
Facing facing;
int backgroundColor = ColorUtils.GRAY;
int unselectedColor = ColorUtils.GRAY;
int selectedColor = ColorUtils.DARK_GRAY;
float padding = 30F;
public SingleTabPanelComponent()
{
this(Facing.NORTH);
}
public SingleTabPanelComponent(Facing facing)
{
this(0F, 0F, 0F, 0F, facing);
}
public SingleTabPanelComponent(float x, float y, float width, float height)
{
this(x, y, width, height, Facing.NORTH);
}
public SingleTabPanelComponent(float x, float y, float width, float height, Facing facing)
{
super(x, y, width, height);
this.facing = facing;
}
public SingleTabPanelComponent setFacing(Facing facing)
{
this.facing = facing;
updateConstrains(selection, createView());
for(Tab tab : tabs)
{
updateConstrains(tab.align(facing.isZAxis() ? Align.CENTER : (facing == Facing.WEST ? Align.LEFT_TOP : Align.RIGHT_BOTTOM)), createConstraint(tab));
}
updateConstrains(panel, createPanel());
onChanged(true);
return this;
}
public SingleTabPanelComponent setPadding(float padding)
{
this.padding = padding;
for(Tab tab : tabs)
{
tab.updatePadding();
}
onChanged(true);
return this;
}
public SingleTabPanelComponent addTab(String name)
{
Tab newTab = new Tab(name).align(facing.isZAxis() ? Align.CENTER : (facing == Facing.WEST ? Align.LEFT_TOP : Align.RIGHT_BOTTOM));
tabs.add(newTab);
if(selectedTab == -1) {
selectedTab = tabs.size()-1;
}
newTab.onAction(() -> selectTab(newTab));
selection.addChild(newTab, createConstraint(newTab));
onChanged(true);
return this;
}
public Facing getFacing()
{
return facing;
}
public int findTab(String name)
{
for(int i = 0,m=tabs.size();i<m;i++) {
if(tabs.get(i).name.equals(name)) return i;
}
return -1;
}
public int getActiveIndex()
{
return selectedTab;
}
public PanelComponent getPanel()
{
return panel;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
getRenderer().drawQuad(selection.getBox(), backgroundColor);
return true;
}
@Override
public void init()
{
addChild(selection, createView());
addChild(panel, createPanel());
super.init();
}
@Override
protected void repaint()
{
if(facing.isZAxis())
{
float room = getBox().getBaseWidth();
float requiredSpace = 0F;
for(int i = 0,m=tabs.size();i<m;i++)
{
Tab tab = tabs.get(i);
float width = tab.getWidth() * tab.getTextScale();
if(i == selectedTab) room -= width;
else requiredSpace += width;
}
tabScale = Math.min(1F, room / requiredSpace);
}
else
{
tabScale = 0F;
for(int i = 0,m=tabs.size();i<m;i++)
{
Tab tab = tabs.get(i);
tabScale = Math.max(tabScale, tab.getWidth() * tab.getTextScale());
}
tabScale *= getBox().getScale();
tabScale += 1F;
}
}
protected Constrains createView()
{
switch(facing)
{
case NORTH: return Constrains.parent(Target.X).parent(Target.Y).parent(Target.WIDTH).height(7.5F).build();
case SOUTH: return Constrains.parent(Target.X).invParent(7.7F, Target.Y).parent(Target.WIDTH).height(7.5F).build();
case EAST: return Constrains.xPos(new DynamicConstrain(this::getXOffset).setInverted(true)).parent(Target.Y).dynamic(this::getPanelWidth, Target.WIDTH).parent(Target.HEIGHT).build();
case WEST: return Constrains.parent(Target.X).parent(Target.Y).dynamic(this::getPanelWidth, Target.WIDTH).parent(Target.HEIGHT).build();
default: return Constrains.parent();
}
}
protected Constrains createPanel()
{
switch(facing)
{
case NORTH: return Constrains.parent(0F, 7.2F, 0F, 3.6F);
case SOUTH: return Constrains.parent(0F, 0F, 0F, 3.6F);
case EAST: return Constrains.parent(Target.X).parent(Target.Y).width(new DynamicConstrain(this::getPanelWidth).setInverted(true)).parent(Target.HEIGHT).build();
case WEST: return Constrains.dynamic(this::getXOffset, Target.X).parent(0F, Target.Y).width(new DynamicConstrain(this::getPanelWidth).setInverted(true)).parent(Target.HEIGHT).build();
default: return Constrains.parent();
}
}
protected Constrains createConstraint(Tab tab)
{
if(facing.isZAxis()) return Constrains.parent(Target.Y).parent(Target.HEIGHT).dynamic(new DynamicTab(tab, this::getOffset), Target.X).dynamic(new DynamicTab(tab, this::getWidth), Target.WIDTH).build();
return Constrains.parent(Target.X).dynamic(new DynamicTab(tab, this::getOffset), Target.Y).parent(Target.WIDTH).height(7.5F).build();
}
protected void selectTab(Tab tab)
{
if(selectTab(tabs.indexOf(tab)))
{
notifyListeners(LISTENER_USER_ACTION);
}
}
public boolean selectTab(int index)
{
if(index < 0 || index >= tabs.size()) return false;
if(selectedTab == index) return false;
selectedTab = index;
onChanged(true);
return true;
}
protected float getOffset(Tab tab)
{
int index = tabs.indexOf(tab);
float offset = 0F;
for(int i = 0;i<index;i++)
{
Tab entry = tabs.get(i);
if(facing.isZAxis()) offset += entry.getWidth() * (i == selectedTab ? 1F : tabScale) * entry.getTextScale();
else offset += tab.getBox().getBaseHeight();
}
return offset;
}
protected float getPanelOffset()
{
return facing == Facing.EAST ? 0F : tabScale + 0.25F;
}
protected float getPanelWidth()
{
return tabScale + 0.25F;
}
protected float getXOffset()
{
return tabScale + 0.25F;
}
protected float getWidth(Tab tab)
{
return facing.isZAxis() ? tab.getWidth() * (selectedTab == tabs.indexOf(tab) ? 1F : tabScale) * tab.getTextScale() : tabScale;
}
private static class DynamicTab implements FloatSupplier
{
Tab tab;
Object2FloatFunction<Tab> function;
public DynamicTab(Tab tab, Object2FloatFunction<Tab> function)
{
this.tab = tab;
this.function = function;
}
@Override
public float getAsFloat()
{
return function.getFloat(tab);
}
}
private class Tab extends GuiComponent implements IButtonComponent
{
String name;
float width = -1F;
TextComponent comp;
public Tab(String name)
{
super(0F, 0F, 100F, 7.5F);
this.name = name;
comp = new TextComponent(name).setTextScale(0.4F).singleLine(true).horizontal(Align.LEFT_TOP);
setFlag(FLAG_SUPPORT_BINDING);
}
public Tab align(Align align)
{
comp.horizontal(align);
return this;
}
public void updatePadding()
{
if(getGui() != null) width = getFont().width(name)+padding;
}
@Override
public void init()
{
addChild(comp, Constrains.parent());
updatePadding();
}
public float getWidth()
{
return width;
}
public float getTextScale()
{
return comp.getTextScale();
}
@Override
protected void repaint()
{
String s = name;
float scale = comp.getTextScale();
float width = (this.width-padding)*scale;
float desiredWidth = getBox().getBaseWidth();
if(width > desiredWidth) {
while(s.length() >= 1 && getFont().width(s+"...") * scale > desiredWidth) {
s = s.substring(0, s.length()-1);
}
comp.setText(s+"...");
return;
}
comp.setText(s);
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
boolean notSelected = tabs.indexOf(this) != selectedTab;
getRenderer().drawQuad(getBox(), notSelected ? unselectedColor : selectedColor);
if(notSelected) getRenderer().drawFrame(getBox(), selectedColor);
return true;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
notifyListeners(LISTENER_USER_ACTION);
}
@Override
protected boolean onUserKey()
{
notifyListeners(LISTENER_USER_ACTION);
return true;
}
}
}

View File

@ -1,202 +1,213 @@
package speiger.src.coreengine.rendering.gui.components;
import java.util.function.IntFunction;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
public class SliderComponent extends GuiComponent implements IButtonComponent
{
TextComponent text = new TextComponent();
protected int color;
protected boolean vertical = false;
protected int min;
protected int max;
protected int value;
int scrollEffect;
IntFunction<String> textBuilder;
protected RenderBuffer buffer;
public SliderComponent(int min, int max, int value, int color, IntFunction<String> textBuilder)
{
this(0F, 0F, 0F, 0F, min, max, value, color, textBuilder);
}
public SliderComponent(float x, float y, float width, float height, int min, int max, int value, int color, IntFunction<String> textBuilder)
{
super(x, y, width, height);
this.min = min;
this.max = max;
this.value = MathUtils.clamp(min, max, value);
this.color = color;
this.textBuilder = textBuilder;
updateText(false);
}
@Override
public void init()
{
text.setTextScale(0.35F);
addChild(text, Constrains.parent());
createArrow();
}
protected void createArrow()
{
if(getGui() == null)
{
return;
}
if(buffer == null)
{
addCloseListener(buffer = getRenderer().createBuffer());
}
buffer.clear();
UIShapes.createArrow(buffer, 12F, 12F, color, vertical ? Facing.EAST : Facing.SOUTH);
}
public TextComponent getText()
{
return text;
}
public SliderComponent updateText(boolean notifyListeners)
{
if(textBuilder != null)
{
text.setText(textBuilder.apply(value));
}
if(notifyListeners)
{
notifyListeners(LISTENER_USER_ACTION);
}
return this;
}
public SliderComponent setColor(int color)
{
if(this.color != color)
{
this.color = color;
createArrow();
}
return this;
}
public SliderComponent setValue(int value)
{
int lastValue = this.value;
this.value = MathUtils.clamp(min, max, value);
if(lastValue != value)
{
updateText(true);
}
return this;
}
public SliderComponent addValue(int value)
{
return setValue(this.value + value);
}
public SliderComponent setScrollEffect(int scrollEffect)
{
this.scrollEffect = scrollEffect;
return this;
}
public SliderComponent setVertical(boolean vertical)
{
if(this.vertical != vertical)
{
this.vertical = vertical;
createArrow();
}
return this;
}
public int getValue()
{
return value;
}
public float getPercentalValue()
{
return ((float)(value - min) / (float)(max - min));
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brightness = getActiveBrightness();
float minX = getBox().getMinX(5F);
float minY = getBox().getMinY(2F);
float maxX = getBox().getMaxX(-5F);
float maxY = getBox().getMaxY(-2F);
float scale = 0.6F * getBox().getScale();
if(vertical)
{
float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxY(-3F) - getBox().getMinY(3F))) + getBox().getMinY(3F);
float left = getBox().getMinX(2F);
getRenderer().setBrightness(brightness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brightness * 0.7F).drawFrame(minX, minY, maxX, maxY, 0.001F, color);
getRenderer().setBrightness(brightness * 0.5F).translate(left, extra, 0.002F).scale(scale).drawBuffers(buffer, maxX - minX, maxX - minX).setBrightness(brightness).unscale(scale).translate(-left, -extra, -0.002F);
}
else
{
float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxX(-6F) - getBox().getMinX(6F))) + getBox().getMinX(6F);
float top = getBox().getMinY();
getRenderer().setBrightness(brightness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brightness * 0.7F).drawFrame(minX, minY, maxX, maxY, 0.001F, color);
getRenderer().setBrightness(brightness * 0.5F).translate(extra, top, 0.002F).scale(scale).drawBuffers(buffer, maxX - minX, maxX - minX).setBrightness(brightness).unscale(scale).translate(-extra, -top, -0.002F);
}
getRenderer().setBrightness(getBrightness(mouseX, mouseY));
renderChildren(mouseX, mouseY, particalTicks);
getRenderer().setBrightness(1F);
return false;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
updateScroll(mouseX, mouseY);
return true;
}
@Override
public boolean onDrag(int mouseX, int mouseY)
{
updateScroll(mouseX, mouseY);
return true;
}
@Override
public boolean onScroll(int scroll, int mouseX, int mouseY)
{
if(scrollEffect != 0)
{
int newValue = MathUtils.clamp(min, max, value + (scroll * scrollEffect));
if(newValue != value)
{
value = newValue;
updateText(true);
}
}
return scrollEffect != 0;
}
public void updateScroll(int mouseX, int mouseY)
{
float pos = vertical ? (mouseY - getBox().getMinY(2F)) / getBox().getHeight(-5F) : (mouseX - getBox().getMinX(5F)) / getBox().getWidth(-11F);
int newValue = min + (int)(MathUtils.clamp(0F, 1F, pos) * (max - min));
if(newValue != value)
{
value = newValue;
updateText(true);
}
}
}
package speiger.src.coreengine.rendering.gui.components;
import java.util.function.IntFunction;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
public class SliderComponent extends GuiComponent implements IButtonComponent
{
TextComponent text = new TextComponent();
protected int color;
protected boolean vertical = false;
protected int min;
protected int max;
protected int value;
int scrollEffect;
IntFunction<String> textBuilder;
protected RenderBuffer buffer;
public SliderComponent(int min, int max, int value, int color, IntFunction<String> textBuilder)
{
this(0F, 0F, 0F, 0F, min, max, value, color, 1F, textBuilder);
}
public SliderComponent(int min, int max, int value, int color, float textScale, IntFunction<String> textBuilder)
{
this(0F, 0F, 0F, 0F, min, max, value, color, textScale, textBuilder);
}
public SliderComponent(float x, float y, float width, float height, int min, int max, int value, int color, IntFunction<String> textBuilder)
{
this(x, y, width, height, min, max, value, color, 1F, textBuilder);
}
public SliderComponent(float x, float y, float width, float height, int min, int max, int value, int color, float textScale, IntFunction<String> textBuilder)
{
super(x, y, width, height);
this.min = min;
this.max = max;
this.value = MathUtils.clamp(min, max, value);
this.color = color;
text.setTextScale(textScale);
this.textBuilder = textBuilder;
updateText(false);
}
@Override
public void init()
{
text.setTextScale(0.35F);
addChild(text, Constrains.parent());
createArrow();
}
protected void createArrow()
{
if(getGui() == null)
{
return;
}
if(buffer == null)
{
onClose(buffer = getRenderer().createBuffer());
}
buffer.clear();
UIShapes.createArrow(buffer, 12F, 12F, color, vertical ? Facing.EAST : Facing.SOUTH);
}
public TextComponent getText()
{
return text;
}
public SliderComponent updateText(boolean notifyListeners)
{
if(textBuilder != null)
{
text.setText(textBuilder.apply(value));
}
if(notifyListeners)
{
notifyListeners(LISTENER_USER_ACTION);
}
return this;
}
public SliderComponent setColor(int color)
{
if(this.color != color)
{
this.color = color;
createArrow();
}
return this;
}
public SliderComponent setValue(int value)
{
int lastValue = this.value;
this.value = MathUtils.clamp(min, max, value);
if(lastValue != value)
{
updateText(true);
}
return this;
}
public SliderComponent addValue(int value)
{
return setValue(this.value + value);
}
public SliderComponent setScrollEffect(int scrollEffect)
{
this.scrollEffect = scrollEffect;
return this;
}
public SliderComponent setVertical(boolean vertical)
{
if(this.vertical != vertical)
{
this.vertical = vertical;
createArrow();
}
return this;
}
public int getValue()
{
return value;
}
public float getPercentalValue()
{
return ((float)(value - min) / (float)(max - min));
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brightness = getActiveBrightness();
float minX = getBox().getMinX(5F);
float minY = getBox().getMinY(2F);
float maxX = getBox().getMaxX(-5F);
float maxY = getBox().getMaxY(-2F);
float scale = 0.6F * getBox().getScale();
if(vertical)
{
float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxY(-3F) - getBox().getMinY(3F))) + getBox().getMinY(3F);
float left = getBox().getMinX(2F);
getRenderer().setBrightness(brightness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brightness * 0.7F).drawFrame(minX, minY, maxX, maxY, 0.001F, color);
getRenderer().setBrightness(brightness * 0.5F).translate(left, extra, 0.002F).scale(scale).drawBuffers(buffer, maxX - minX, maxX - minX).setBrightness(brightness).unscale(scale).translate(-left, -extra, -0.002F);
}
else
{
float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxX(-6F) - getBox().getMinX(6F))) + getBox().getMinX(6F);
float top = getBox().getMinY();
getRenderer().setBrightness(brightness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brightness * 0.7F).drawFrame(minX, minY, maxX, maxY, 0.001F, color);
getRenderer().setBrightness(brightness * 0.5F).translate(extra, top, 0.002F).scale(scale).drawBuffers(buffer, maxX - minX, maxX - minX).setBrightness(brightness).unscale(scale).translate(-extra, -top, -0.002F);
}
getRenderer().setBrightness(getBrightness(mouseX, mouseY));
renderChildren(mouseX, mouseY, particalTicks);
getRenderer().setBrightness(1F);
return false;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
updateScroll(mouseX, mouseY);
return true;
}
@Override
public boolean onDrag(int mouseX, int mouseY)
{
updateScroll(mouseX, mouseY);
return true;
}
@Override
public boolean onScroll(int scroll, int mouseX, int mouseY)
{
if(scrollEffect != 0)
{
int newValue = MathUtils.clamp(min, max, value + (scroll * scrollEffect));
if(newValue != value)
{
value = newValue;
updateText(true);
}
}
return scrollEffect != 0;
}
public void updateScroll(int mouseX, int mouseY)
{
float pos = vertical ? (mouseY - getBox().getMinY(2F)) / getBox().getHeight(-5F) : (mouseX - getBox().getMinX(5F)) / getBox().getWidth(-11F);
int newValue = min + (int)(MathUtils.clamp(0F, 1F, pos) * (max - min));
if(newValue != value)
{
value = newValue;
updateText(true);
}
}
}

View File

@ -0,0 +1,339 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.collections.objects.functions.function.Object2FloatFunction;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
import speiger.src.coreengine.utils.functions.FloatSupplier;
public class TabbedPanelComponent extends PanelComponent
{
PanelComponent selection = new PanelComponent();
ObjectList<Tab> tabs = new ObjectArrayList<>();
int selectedTab = -1;
float tabScale = 1F;
Facing facing;
int backgroundColor = ColorUtils.GRAY;
int unselectedColor = ColorUtils.GRAY;
int selectedColor = ColorUtils.DARK_GRAY;
float padding = 30F;
public TabbedPanelComponent()
{
this(Facing.NORTH);
}
public TabbedPanelComponent(Facing facing)
{
this(0F, 0F, 0F, 0F, facing);
}
public TabbedPanelComponent(float x, float y, float width, float height)
{
this(x, y, width, height, Facing.NORTH);
}
public TabbedPanelComponent(float x, float y, float width, float height, Facing facing)
{
super(x, y, width, height);
this.facing = facing;
}
public TabbedPanelComponent setFacing(Facing facing)
{
this.facing = facing;
updateConstrains(selection, createView());
for(Tab tab : tabs)
{
updateConstrains(tab.align(facing.isZAxis() ? Align.CENTER : (facing == Facing.WEST ? Align.LEFT_TOP : Align.RIGHT_BOTTOM)), createConstraint(tab));
updateConstrains(tab.getPanel(), createPanel());
}
onChanged(true);
return this;
}
public TabbedPanelComponent setPadding(float padding)
{
this.padding = padding;
for(Tab tab : tabs)
{
tab.updatePadding();
}
onChanged(true);
return this;
}
public Facing getFacing()
{
return facing;
}
public PanelComponent addTab(String name)
{
Tab newTab = new Tab(name).align(facing.isZAxis() ? Align.CENTER : (facing == Facing.WEST ? Align.LEFT_TOP : Align.RIGHT_BOTTOM));
tabs.add(newTab);
if(selectedTab == -1) {
selectedTab = tabs.size()-1;
newTab.getPanel().setVisible(true);
}
newTab.onAction(() -> selectTab(newTab));
selection.addChild(newTab, createConstraint(newTab));
addChild(newTab.getPanel(), createPanel());
onChanged(true);
return newTab.getPanel();
}
public int findTab(String name)
{
for(int i = 0,m=tabs.size();i<m;i++) {
if(tabs.get(i).name.equals(name)) return i;
}
return -1;
}
public int getActiveIndex()
{
return selectedTab;
}
public PanelComponent getActiveTab()
{
return selectedTab == -1 ? null : tabs.get(selectedTab).getPanel();
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
getRenderer().drawQuad(selection.getBox(), backgroundColor);
return true;
}
@Override
public void init()
{
addChild(selection, createView());
super.init();
}
@Override
protected void repaint()
{
if(facing.isZAxis())
{
float room = getBox().getBaseWidth();
float requiredSpace = 0F;
for(int i = 0,m=tabs.size();i<m;i++)
{
Tab tab = tabs.get(i);
float width = tab.getWidth() * tab.getTextScale();
if(i == selectedTab) room -= width;
else requiredSpace += width;
}
tabScale = Math.min(1F, room / requiredSpace);
}
else
{
tabScale = 0F;
for(int i = 0,m=tabs.size();i<m;i++)
{
Tab tab = tabs.get(i);
tabScale = Math.max(tabScale, tab.getWidth() * tab.getTextScale());
}
tabScale *= getBox().getScale();
tabScale += 1F;
}
}
protected Constrains createView()
{
switch(facing)
{
case NORTH: return Constrains.parent(Target.X).parent(Target.Y).parent(Target.WIDTH).height(7.5F).build();
case SOUTH: return Constrains.parent(Target.X).invParent(7.7F, Target.Y).parent(Target.WIDTH).height(7.5F).build();
case EAST: return Constrains.xPos(new DynamicConstrain(this::getXOffset).setInverted(true)).parent(Target.Y).dynamic(this::getPanelWidth, Target.WIDTH).parent(Target.HEIGHT).build();
case WEST: return Constrains.parent(Target.X).parent(Target.Y).dynamic(this::getPanelWidth, Target.WIDTH).parent(Target.HEIGHT).build();
default: return Constrains.parent();
}
}
protected Constrains createPanel()
{
switch(facing)
{
case NORTH: return Constrains.parent(0F, 7.2F, 0F, 3.6F);
case SOUTH: return Constrains.parent(0F, 0F, 0F, 3.6F);
case EAST: return Constrains.parent(Target.X).parent(Target.Y).width(new DynamicConstrain(this::getPanelWidth).setInverted(true)).parent(Target.HEIGHT).build();
case WEST: return Constrains.dynamic(this::getXOffset, Target.X).parent(0F, Target.Y).width(new DynamicConstrain(this::getPanelWidth).setInverted(true)).parent(Target.HEIGHT).build();
default: return Constrains.parent();
}
}
protected Constrains createConstraint(Tab tab)
{
if(facing.isZAxis()) return Constrains.parent(Target.Y).parent(Target.HEIGHT).dynamic(new DynamicTab(tab, this::getOffset), Target.X).dynamic(new DynamicTab(tab, this::getWidth), Target.WIDTH).build();
return Constrains.parent(Target.X).dynamic(new DynamicTab(tab, this::getOffset), Target.Y).parent(Target.WIDTH).height(7.5F).build();
}
protected void selectTab(Tab tab)
{
selectTab(tabs.indexOf(tab));
}
public boolean selectTab(int index)
{
if(index < 0 || index >= tabs.size()) return false;
if(selectedTab == index) return false;
if(selectedTab != -1) tabs.get(selectedTab).getPanel().setVisible(false);
selectedTab = index;
tabs.get(selectedTab).getPanel().setVisible(true);
onChanged(true);
return true;
}
protected float getOffset(Tab tab)
{
int index = tabs.indexOf(tab);
float offset = 0F;
for(int i = 0;i<index;i++)
{
Tab entry = tabs.get(i);
if(facing.isZAxis()) offset += entry.getWidth() * (i == selectedTab ? 1F : tabScale) * entry.getTextScale();
else offset += tab.getBox().getBaseHeight();
}
return offset;
}
protected float getPanelOffset()
{
return facing == Facing.EAST ? 0F : tabScale + 0.25F;
}
protected float getPanelWidth()
{
return tabScale + 0.25F;
}
protected float getXOffset()
{
return tabScale + 0.25F;
}
protected float getWidth(Tab tab)
{
return facing.isZAxis() ? tab.getWidth() * (selectedTab == tabs.indexOf(tab) ? 1F : tabScale) * tab.getTextScale() : tabScale;
}
private static class DynamicTab implements FloatSupplier
{
Tab tab;
Object2FloatFunction<Tab> function;
public DynamicTab(Tab tab, Object2FloatFunction<Tab> function)
{
this.tab = tab;
this.function = function;
}
@Override
public float getAsFloat()
{
return function.getFloat(tab);
}
}
private class Tab extends GuiComponent implements IButtonComponent
{
String name;
float width = -1F;
TextComponent comp;
PanelComponent panel = new PanelComponent().setScissors(true).setVisible(false).cast();
public Tab(String name)
{
super(0F, 0F, 100F, 7.5F);
this.name = name;
comp = new TextComponent(name).setTextScale(0.4F).singleLine(true).horizontal(Align.LEFT_TOP);
setFlag(FLAG_SUPPORT_BINDING);
}
public Tab align(Align align)
{
comp.horizontal(align);
return this;
}
public void updatePadding()
{
if(getGui() != null) width = getFont().width(name)+padding;
}
@Override
public void init()
{
addChild(comp, Constrains.parent());
updatePadding();
}
public float getWidth()
{
return width;
}
public float getTextScale()
{
return comp.getTextScale();
}
@Override
protected void repaint()
{
String s = name;
float scale = comp.getTextScale();
float width = (this.width-padding)*scale;
float desiredWidth = getBox().getBaseWidth();
if(width > desiredWidth) {
while(s.length() >= 1 && getFont().width(s+"...") * scale > desiredWidth) {
s = s.substring(0, s.length()-1);
}
comp.setText(s+"...");
return;
}
comp.setText(s);
}
public PanelComponent getPanel()
{
return panel;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
boolean notSelected = tabs.indexOf(this) != selectedTab;
getRenderer().drawQuad(getBox(), notSelected ? unselectedColor : selectedColor);
if(notSelected) getRenderer().drawFrame(getBox(), selectedColor);
return true;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
notifyListeners(LISTENER_USER_ACTION);
}
@Override
protected boolean onUserKey()
{
notifyListeners(LISTENER_USER_ACTION);
return true;
}
}
}

View File

@ -1,61 +0,0 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
public class TabbedWindowComponent extends WindowComponent
{
public TabbedWindowComponent(float x, float y, float width, float height)
{
super(x, y, width, height, DEFAULT_FLAGS, "Test");
}
@Override
public void init()
{
super.init();
addChild(new Tab("Testing My theory with the full lenght text"), null, null, new ParentConstrain(), null);
}
public static class Tab extends GuiComponent
{
String name;
float width = -1F;
boolean closeable;
TextComponent comp;
public Tab(String name)
{
super(0F, 7F, 100F, 10F);
this.name = name;
comp = new TextComponent(name).setTextScale(0.4F).singleLine(true).horizontal(Align.LEFT_TOP);
}
@Override
public void init()
{
width = getFont().width(name);
addChild(comp, Constrains.parent());
}
@Override
protected void repaint()
{
String s = name;
float scale = comp.getTextScale();
float width = getFont().width(s)*scale;
float desiredWidth = getBox().getBaseWidth();
if(width > desiredWidth) {
while(getFont().width(s+"...") * scale > desiredWidth) {
s = s.substring(0, s.length()-1);
}
comp.setText(s+"...");
return;
}
comp.setText(s);
}
}
}

View File

@ -1,437 +1,437 @@
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.renderer.FontRenderer;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
import speiger.src.coreengine.rendering.gui.renderer.lexer.TextMetadata;
public class TextComponent extends GuiComponent
{
public static final int FLAG_STRIKE_THROUGH = 1 << 20;
public static final int FLAG_UNDERLINE = 1 << 21;
public static final int FLAG_BOLD = 1 << 22;
public static final int FLAG_FORMATTING = 1 << 23;
public static final int FLAG_FLIPPED = 1 << 24;
public static final int FLAG_LIMITED_WIDTH = 1 << 25;
public static final int FLAG_LIMITED_HEIGHT = 1 << 26;
public static final int FLAG_AUTO_SCALE = 1 << 27;
public static final int FLAG_SINGLE_LINE = 1 << 28;
FontRenderer font;
String text = "";
Align vertical = Align.CENTER;
Align horizontal = Align.CENTER;
int textColor = ColorUtils.WHITE;
Integer backGroundColor = null;
float italic = 0F;
float textScale = 1F;
RenderBuffer buffer;
float initialSize;
TextMetadata metadata = new TextMetadata(this);
public TextComponent()
{
super(0F, 0F, 0F, 0F);
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
}
public TextComponent(String text)
{
this(0F, 0F, 0F, 0F, text);
}
public TextComponent(float x, float y, float width, float height)
{
super(x, y, width, height);
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
}
public TextComponent(float x, float y, float width, float height, String text)
{
super(x, y, width, height);
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
setText(text);
}
@Override
public void init()
{
addCloseListener(buffer = getRenderer().createBuffer());
if(font == null)
{
setFont(getGui().getFont());
}
initialSize = getBox().getWidth();
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
if(text.isEmpty())
{
return true;
}
float minX = getBox().getMinX();
float minY = getBox().getMinY();
getRenderer().translate(minX, minY).setActiveTexture(font.getTexture()).drawBuffers(buffer, getBox().getWidth(), getBox().getHeight()).translate(-minX, -minY);
return true;
}
@Override
public void calculateActualBounds(float[] area, boolean start)
{
if(start)
{
area[0] = Float.MAX_VALUE;
area[1] = Float.MAX_VALUE;
area[2] = Float.MIN_VALUE;
area[3] = Float.MIN_VALUE;
}
IGuiBox box = getBox();
area[0] = Math.min(area[0], box.getMinX() - metadata.getStartX());
area[1] = Math.min(area[1], box.getMinY() - metadata.getStartY());
area[2] = Math.max(area[2], (box.getMinX() - metadata.getStartX()) + metadata.getMaxWidth());
area[3] = Math.max(area[3], (box.getMinY() - metadata.getStartY()) + metadata.getMaxHeight());
for(GuiComponent comp : getChildren())
{
if(comp.isVisible()) comp.calculateActualBounds(area, false);
}
}
public RenderBuffer getBuffer()
{
return buffer;
}
@Override
protected void repaint()
{
metadata.clear();
if(font == null)
{
return;
}
font.updateText(this);
}
public TextComponent setTextScale(float textScale)
{
if(this.textScale != textScale)
{
this.textScale = textScale;
onChanged(true);
}
return this;
}
public TextMetadata getMetadata()
{
return metadata;
}
public final float getTextScale()
{
return textScale * getBox().getScale() * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F);
}
public final float getRawTextScale()
{
return textScale * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F);
}
public final float getWidth()
{
return getBox().getWidth() / getTextScale();
}
public final float getItalic()
{
return italic;
}
public final boolean isBold()
{
return isFlagSet(FLAG_BOLD);
}
public final boolean isStrikeThrough()
{
return isFlagSet(FLAG_STRIKE_THROUGH);
}
public final boolean isUnderlined()
{
return isFlagSet(FLAG_UNDERLINE);
}
public final boolean isFlipped()
{
return isFlagSet(FLAG_FLIPPED);
}
public final boolean isRenderingSpecial()
{
return isFlagSet(FLAG_FORMATTING);
}
public final boolean isWidthLimited()
{
return isFlagSet(FLAG_LIMITED_WIDTH);
}
public final boolean isHeightLimited()
{
return isFlagSet(FLAG_LIMITED_HEIGHT);
}
public final boolean isLimitedText()
{
return isFlagSet(FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
}
public final boolean isAutoScaling()
{
return isFlagSet(FLAG_AUTO_SCALE);
}
public final boolean isForcedSingleLine()
{
return isFlagSet(FLAG_SINGLE_LINE);
}
public final int getTextColor()
{
return textColor;
}
public final Integer getBackgroundColor()
{
return backGroundColor;
}
@Override
public FontRenderer getFont()
{
return font;
}
public String getText()
{
return text;
}
public String getText(int min)
{
return text.substring(min);
}
public String getText(int min, int max)
{
return text.substring(min, max);
}
public int length()
{
return text.length();
}
public Align getVertical()
{
return vertical;
}
public Align getHorizontal()
{
return horizontal;
}
public final TextComponent bold(boolean value)
{
if(setFlag(FLAG_BOLD, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent strikethrough(boolean value)
{
if(!setFlag(FLAG_STRIKE_THROUGH, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent underline(boolean value)
{
if(!setFlag(FLAG_UNDERLINE, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent flipped(boolean value)
{
if(!setFlag(FLAG_FLIPPED, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent special(boolean value)
{
if(!setFlag(FLAG_FORMATTING, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent limit(boolean value)
{
if(!setFlag(FLAG_LIMITED_HEIGHT | FLAG_LIMITED_WIDTH, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent limitWidth(boolean value)
{
if(!setFlag(FLAG_LIMITED_WIDTH, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent limitHeight(boolean value)
{
if(!setFlag(FLAG_LIMITED_HEIGHT, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent autoScale(boolean value)
{
if(!setFlag(FLAG_AUTO_SCALE, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent singleLine(boolean value)
{
if(!setFlag(FLAG_SINGLE_LINE, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent italic(boolean value)
{
return italic(value ? 3F : 0F);
}
public final TextComponent italic(float value)
{
if(italic != value)
{
italic = value;
onChanged(true);
}
return this;
}
public TextComponent align(Align horizontal, Align vertical)
{
if(this.horizontal != horizontal || this.vertical != vertical)
{
this.horizontal = horizontal;
this.vertical = vertical;
onChanged(true);
}
return this;
}
public TextComponent horizontal(Align horizontal)
{
if(this.horizontal != horizontal)
{
this.horizontal = horizontal;
onChanged(true);
}
return this;
}
public TextComponent vertical(Align vertical)
{
if(this.vertical != vertical)
{
this.vertical = vertical;
onChanged(true);
}
return this;
}
public TextComponent setText(String text)
{
if(text == null) text = "null";
if(!this.text.equals(text))
{
this.text = text;
onChanged(true);
}
return this;
}
public TextComponent textColor(int color)
{
if(textColor != color)
{
textColor = color;
onChanged(true);
}
return this;
}
public TextComponent backgroundColor(int color)
{
if(backGroundColor != color)
{
backGroundColor = color;
onChanged(true);
}
return this;
}
public TextComponent setFont(FontRenderer font)
{
if(this.font != font)
{
this.font = font;
onChanged(true);
}
return this;
}
}
package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.renderer.FontRenderer;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
import speiger.src.coreengine.rendering.gui.renderer.lexer.TextMetadata;
public class TextComponent extends GuiComponent
{
public static final int FLAG_STRIKE_THROUGH = 1 << 20;
public static final int FLAG_UNDERLINE = 1 << 21;
public static final int FLAG_BOLD = 1 << 22;
public static final int FLAG_FORMATTING = 1 << 23;
public static final int FLAG_FLIPPED = 1 << 24;
public static final int FLAG_LIMITED_WIDTH = 1 << 25;
public static final int FLAG_LIMITED_HEIGHT = 1 << 26;
public static final int FLAG_AUTO_SCALE = 1 << 27;
public static final int FLAG_SINGLE_LINE = 1 << 28;
FontRenderer font;
String text = "";
Align vertical = Align.CENTER;
Align horizontal = Align.CENTER;
int textColor = ColorUtils.WHITE;
Integer backGroundColor = null;
float italic = 0F;
float textScale = 1F;
RenderBuffer buffer;
float initialSize;
TextMetadata metadata = new TextMetadata(this);
public TextComponent()
{
super(0F, 0F, 0F, 0F);
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
}
public TextComponent(String text)
{
this(0F, 0F, 0F, 0F, text);
}
public TextComponent(float x, float y, float width, float height)
{
super(x, y, width, height);
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
}
public TextComponent(float x, float y, float width, float height, String text)
{
super(x, y, width, height);
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
setText(text);
}
@Override
public void init()
{
onClose(buffer = getRenderer().createBuffer());
if(font == null)
{
setFont(getGui().getFont());
}
initialSize = getBox().getWidth();
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
if(text.isEmpty())
{
return true;
}
float minX = getBox().getMinX();
float minY = getBox().getMinY();
getRenderer().translate(minX, minY).setActiveTexture(font.getTexture()).drawBuffers(buffer, getBox().getWidth(), getBox().getHeight()).translate(-minX, -minY);
return true;
}
@Override
public void calculateActualBounds(float[] area, boolean start)
{
if(start)
{
area[0] = Float.MAX_VALUE;
area[1] = Float.MAX_VALUE;
area[2] = Float.MIN_VALUE;
area[3] = Float.MIN_VALUE;
}
IGuiBox box = getBox();
area[0] = Math.min(area[0], box.getMinX() - metadata.getStartX());
area[1] = Math.min(area[1], box.getMinY() - metadata.getStartY());
area[2] = Math.max(area[2], (box.getMinX() - metadata.getStartX()) + metadata.getMaxWidth());
area[3] = Math.max(area[3], (box.getMinY() - metadata.getStartY()) + metadata.getMaxHeight());
for(GuiComponent comp : getChildren())
{
if(comp.isVisible()) comp.calculateActualBounds(area, false);
}
}
public RenderBuffer getBuffer()
{
return buffer;
}
@Override
protected void repaint()
{
metadata.clear();
if(font == null)
{
return;
}
font.updateText(this);
}
public TextComponent setTextScale(float textScale)
{
if(this.textScale != textScale)
{
this.textScale = textScale;
onChanged(true);
}
return this;
}
public TextMetadata getMetadata()
{
return metadata;
}
public final float getTextScale()
{
return textScale * getBox().getScale() * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F);
}
public final float getRawTextScale()
{
return textScale * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F);
}
public final float getWidth()
{
return getBox().getWidth() / getTextScale();
}
public final float getItalic()
{
return italic;
}
public final boolean isBold()
{
return isFlagSet(FLAG_BOLD);
}
public final boolean isStrikeThrough()
{
return isFlagSet(FLAG_STRIKE_THROUGH);
}
public final boolean isUnderlined()
{
return isFlagSet(FLAG_UNDERLINE);
}
public final boolean isFlipped()
{
return isFlagSet(FLAG_FLIPPED);
}
public final boolean isRenderingSpecial()
{
return isFlagSet(FLAG_FORMATTING);
}
public final boolean isWidthLimited()
{
return isFlagSet(FLAG_LIMITED_WIDTH);
}
public final boolean isHeightLimited()
{
return isFlagSet(FLAG_LIMITED_HEIGHT);
}
public final boolean isLimitedText()
{
return isFlagSet(FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
}
public final boolean isAutoScaling()
{
return isFlagSet(FLAG_AUTO_SCALE);
}
public final boolean isForcedSingleLine()
{
return isFlagSet(FLAG_SINGLE_LINE);
}
public final int getTextColor()
{
return textColor;
}
public final Integer getBackgroundColor()
{
return backGroundColor;
}
@Override
public FontRenderer getFont()
{
return font;
}
public String getText()
{
return text;
}
public String getText(int min)
{
return text.substring(min);
}
public String getText(int min, int max)
{
return text.substring(min, max);
}
public int length()
{
return text.length();
}
public Align getVertical()
{
return vertical;
}
public Align getHorizontal()
{
return horizontal;
}
public final TextComponent bold(boolean value)
{
if(setFlag(FLAG_BOLD, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent strikethrough(boolean value)
{
if(!setFlag(FLAG_STRIKE_THROUGH, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent underline(boolean value)
{
if(!setFlag(FLAG_UNDERLINE, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent flipped(boolean value)
{
if(!setFlag(FLAG_FLIPPED, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent special(boolean value)
{
if(!setFlag(FLAG_FORMATTING, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent limit(boolean value)
{
if(!setFlag(FLAG_LIMITED_HEIGHT | FLAG_LIMITED_WIDTH, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent limitWidth(boolean value)
{
if(!setFlag(FLAG_LIMITED_WIDTH, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent limitHeight(boolean value)
{
if(!setFlag(FLAG_LIMITED_HEIGHT, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent autoScale(boolean value)
{
if(!setFlag(FLAG_AUTO_SCALE, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent singleLine(boolean value)
{
if(!setFlag(FLAG_SINGLE_LINE, value))
{
return this;
}
onChanged(true);
return this;
}
public final TextComponent italic(boolean value)
{
return italic(value ? 3F : 0F);
}
public final TextComponent italic(float value)
{
if(italic != value)
{
italic = value;
onChanged(true);
}
return this;
}
public TextComponent align(Align horizontal, Align vertical)
{
if(this.horizontal != horizontal || this.vertical != vertical)
{
this.horizontal = horizontal;
this.vertical = vertical;
onChanged(true);
}
return this;
}
public TextComponent horizontal(Align horizontal)
{
if(this.horizontal != horizontal)
{
this.horizontal = horizontal;
onChanged(true);
}
return this;
}
public TextComponent vertical(Align vertical)
{
if(this.vertical != vertical)
{
this.vertical = vertical;
onChanged(true);
}
return this;
}
public TextComponent setText(String text)
{
if(text == null) text = "null";
if(!this.text.equals(text))
{
this.text = text;
onChanged(true);
}
return this;
}
public TextComponent textColor(int color)
{
if(textColor != color)
{
textColor = color;
onChanged(true);
}
return this;
}
public TextComponent backgroundColor(int color)
{
if(backGroundColor != color)
{
backGroundColor = color;
onChanged(true);
}
return this;
}
public TextComponent setFont(FontRenderer font)
{
if(this.font != font)
{
this.font = font;
onChanged(true);
}
return this;
}
}

View File

@ -1,356 +1,364 @@
package speiger.src.coreengine.rendering.gui.components;
import java.util.function.Consumer;
import java.util.function.ObjIntConsumer;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.math.misc.FacingList;
import speiger.src.coreengine.math.value.IValue;
import speiger.src.coreengine.math.value.LiniarValue;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.math.vector.ints.Vec2i;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.components.icon.CrossIcon;
import speiger.src.coreengine.rendering.gui.components.icon.LineIcon;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.utils.Cursor;
import speiger.src.coreengine.utils.functions.ConsumerConverter;
import speiger.src.coreengine.utils.helpers.InternalThreadPools;
public class WindowComponent extends PanelComponent implements IButtonComponent, ObjIntConsumer<GuiComponent>
{
public static final Vec2f DEFAULT_MINIMUM_BOUNDS = Vec2f.of(75F, 7.5F);
public static final int FLAG_MINIMIZED = 1 << 20;
public static final int FLAG_RESIZEABLE = 1 << 21;
public static final int FLAG_MOVEABLE = 1 << 22;
public static final int FLAG_RESIZEABLE_HORIZONTAL = 1 << 23;
public static final int FLAG_RESIZEABLE_VERTICAL = 1 << 24;
public static final int FLAG_RESIZE_INVERT = 1 << 25;
public static final int WINDOW_FLAG_CLOSEABLE = 1;
public static final int WINDOW_FLAG_MINIMIZEABLE = 2;
public static final int WINDOW_FLAGS = WINDOW_FLAG_CLOSEABLE | WINDOW_FLAG_MINIMIZEABLE;
public static final int DEFAULT_FLAGS = WINDOW_FLAGS | FLAG_RESIZEABLE | FLAG_MOVEABLE;
public static final int FIXED_SIZE_WINDOW = WINDOW_FLAGS | FLAG_MOVEABLE;
public static final int FIXED_SIZE_POPUP = WINDOW_FLAG_CLOSEABLE | FLAG_MOVEABLE;
public static final int DYNAMIC_POPUP = FIXED_SIZE_POPUP | FLAG_RESIZEABLE;
public static final int UNCLOSEABLE_WINDOW = WINDOW_FLAG_MINIMIZEABLE | FLAG_RESIZEABLE | FLAG_MOVEABLE;
public static final int SUB_WINDOW = WINDOW_FLAG_MINIMIZEABLE | FLAG_RESIZEABLE | FLAG_RESIZE_INVERT;
final int flags;
FacingList facing = null;
String name;
int color = ColorUtils.WINDOW_DEFAULT_BACKGROUND;
Vec2f lastSize = Vec2f.mutable();
Vec2i lastClick = Vec2i.mutable();
IValue animation = null;
protected final Consumer<GuiComponent> closeListener = new ConsumerConverter<GuiComponent>(0, this);
protected final Consumer<GuiComponent> minimizedListener = new ConsumerConverter<GuiComponent>(2, this);
public WindowComponent(float x, float y, float width, float height, int flags, String name)
{
super(x, y, width, height);
this.name = name;
this.flags = flags & WINDOW_FLAGS;
setFlag(flags &= ~(WINDOW_FLAGS));
setFlag(FLAG_RESIZEABLE_HORIZONTAL | FLAG_RESIZEABLE_VERTICAL);
lastSize.set(getBox().getBaseWidth(), getBox().getBaseHeight());
}
@Override
public void init()
{
super.init();
LabelComponent label = new LabelComponent(name, ColorUtils.DARK_GRAY);
label.getText().setTextScale(0.4F).horizontal(Align.LEFT_TOP).singleLine(true);
addChild(label, new Constrains(null, null, new ParentConstrain(), new PixelConstrain(7.5F)));
float offset = 9F;
if((flags & WINDOW_FLAG_CLOSEABLE) != 0)
{
addChild(new IconButtonComponent(0F, 0F, 7.5F, 7.5F, ColorUtils.RED, new CrossIcon(ColorUtils.WHITE).setPadding(2.5F, 2F)).addUserActionListener(new ConsumerConverter<>(0, this)).setZOffset(0.001F), new Constrains(new PixelConstrain(offset).setInverted(), null, null, null));
offset += 7.5F;
}
if((flags & WINDOW_FLAG_MINIMIZEABLE) != 0)
{
addChild(new IconButtonComponent(0F, 0F, 7.5F, 7.5F, ColorUtils.GRAY, new LineIcon(ColorUtils.WHITE, 0.7F, 0.25F)).addUserActionListener(new ConsumerConverter<>(1, this)).setZOffset(0.001F), new Constrains(new PixelConstrain(offset).setInverted(), null, null, null));
}
if(canMoveIntoForground())
{
setFlag(FLAG_RENDER_ORDER);
}
}
protected void updateMinizedState(boolean value)
{
if(setFlag(FLAG_MINIMIZED, value))
{
onChanged(false);
}
}
public final WindowComponent setMinimized(boolean value)
{
if((flags & WINDOW_FLAG_MINIMIZEABLE) != 0 && setFlag(FLAG_MINIMIZED, value))
{
if(value)
{
Vec2f last = InternalThreadPools.VEC2F.get().set(lastSize);
bounds(last.getX(), isFlagSet(FLAG_MINIMIZED) ? getMinimizedY() : last.getY());
lastSize.set(last);
InternalThreadPools.VEC2F.accept(last.negate());
}
else bounds(lastSize.getX(), lastSize.getY());
onChanged(false);
}
return this;
}
public final boolean isMinimized()
{
return isFlagSet(FLAG_MINIMIZED);
}
public Vec2f getMinimumBounds()
{
return DEFAULT_MINIMUM_BOUNDS;
}
public float getMinimizedY()
{
return 7.5F;
}
public WindowComponent setColor(int color)
{
this.color = color;
return this;
}
@Override
public void calculateActualBounds(float[] area, boolean start)
{
if(animation != null)
{
float scale = getBox().getScale();
area[0] = Math.min(area[0], getBox().getMinX());
area[1] = Math.min(area[1], getBox().getMinY());
area[2] = Math.max(area[2], lastSize.getX() * scale);
area[3] = Math.max(area[3], animation.get(getMinimizedY(), lastSize.getY()) * scale);
return;
}
super.calculateActualBounds(area, start);
}
@Override
protected void updateState()
{
if(animation == null)
{
if(isFlagSet(FLAG_MINIMIZED))
{
lastSize.setX(getBox().getBaseWidth());
return;
}
lastSize.set(getBox().getBaseWidth(), getBox().getBaseHeight());
}
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
if(animation != null)
{
animation.update(particalTicks);
if(animation.isDone())
{
if(animation.get() < 0.1F)
{
updateMinizedState(true);
}
Vec2f last = InternalThreadPools.VEC2F.get().set(lastSize);
bounds(last.getX(), isFlagSet(FLAG_MINIMIZED) ? getMinimizedY() : last.getY());
lastSize.set(last);
InternalThreadPools.VEC2F.accept(last.negate());
animation = null;
}
notifyListeners(LISTENER_ON_CHANGE);
}
else if(isFlagSet(FLAG_RESIZEABLE) && !isOverChild(mouseX, mouseY) && !getGui().hasComponentInTheWay(getTopComponent(), mouseX, mouseY))
{
FacingList list = getBox().isColiding(mouseX, mouseY) ? getBox().getColidingBorder(mouseX, mouseY, 2F) : null;
if(list != null)
{
if(isFlagNotSet(FLAG_RESIZEABLE_HORIZONTAL)) list = list.remove(FacingList.HORIZONTAL);
if(isFlagNotSet(FLAG_RESIZEABLE_VERTICAL)) list = list.remove(FacingList.VERTICAL);
bindCursor(list.containsAny(FacingList.VERTICAL) && isFlagNotSet(FLAG_MINIMIZED) ? Cursor.CURSOR_VRESIZE : (list.containsAny(FacingList.HORIZONTAL) ? Cursor.CURSOR_HRESIZE : null));
}
}
if(isPopup() && !hasChildPopups() && !getGui().isComponentInFront(this))
{
requestFocus();
}
return true;
}
@Override
protected void preRender()
{
if(animation != null)
{
float scale = getBox().getScale();
enableScissors(getBox().getMinX(), getBox().getMinY(), lastSize.getX() * scale, animation.get(getMinimizedY(), lastSize.getY()) * scale);
}
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
getRenderer().drawQuad(getBox(), color);
return true;
}
@Override
protected void postRender()
{
if(animation != null)
{
disableScissors();
}
}
@Override
public void accept(GuiComponent value, int index)
{
switch(index)
{
case 0:
getGui().removeComponent(this);
break;
case 1:
if(animation != null || (flags & WINDOW_FLAG_MINIMIZEABLE) == 0)
{
break;
}
animation = (isMinimized() ? new LiniarValue(1F, 0F, 1F) : new LiniarValue(1F, 1F, 0F)).setSmooth();
if(isMinimized())
{
bounds(lastSize.getX(), lastSize.getY());
}
updateMinizedState(false);
break;
case 2:
value.setVisible(!isMinimized());
break;
}
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
if(isOverChild(mouseX, mouseY) || getGui().hasComponentInTheWay(getTopComponent(), mouseX, mouseY))
{
return false;
}
facing = getBox().getColidingBorder(mouseX, mouseY, 2F);
lastClick.set(mouseX, mouseY);
if(facing != null)
{
if(isFlagNotSet(FLAG_RESIZEABLE_HORIZONTAL)) facing = facing.remove(FacingList.HORIZONTAL);
if(isFlagNotSet(FLAG_RESIZEABLE_VERTICAL)) facing = facing.remove(FacingList.VERTICAL);
}
return true;
}
@Override
public boolean onDrag(int mouseX, int mouseY)
{
if(facing != null)
{
if(facing.isEmpty() && isFlagSet(FLAG_MOVEABLE))
{
move(mouseX - lastClick.getX(), mouseY - lastClick.getY());
}
else if(!facing.isEmpty() && isFlagSet(FLAG_RESIZEABLE))
{
float scale = getBox().getScale();
float xChange = (mouseX - lastClick.getX()) * (facing.containsAny(FacingList.HORIZONTAL) ? 1F : 0F);
float yChange = (mouseY - lastClick.getY()) * (facing.containsAny(FacingList.VERTICAL) ? 1F : 0F);
if(isFlagSet(FLAG_RESIZE_INVERT))
{
xChange *= -1F;
yChange *= -1F;
}
setMassChanging();
if(facing.contains(Facing.NORTH) && isFlagNotSet(FLAG_MINIMIZED))
{
resize(0F, -(yChange / scale));
move(0F, yChange);
}
else if(facing.contains(Facing.SOUTH) && isFlagNotSet(FLAG_MINIMIZED))
{
resize(0F, yChange / scale);
}
if(facing.contains(Facing.WEST))
{
resize(-(xChange / scale) - 1F, 0F);
move(xChange, 0F);
}
else if(facing.contains(Facing.EAST))
{
resize(xChange / scale, 0F);
}
ensureMinimumBounds();
finishMassChanging();
if(xChange > 0F || yChange > 0F)
{
onChanged(true);
}
}
lastClick.set(mouseX, mouseY);
return true;
}
return false;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
facing = null;
}
@Override
public boolean canMoveIntoForground()
{
return true;
}
@Override
public void onFocusLost()
{
facing = null;
}
protected void ensureMinimumBounds()
{
IGuiBox box = getBox();
Vec2f bounds = getMinimumBounds();
if(box.getBaseWidth() < bounds.getX())
{
box.setWidth(bounds.getX());
onChanged(true);
}
if(box.getBaseHeight() < bounds.getY())
{
box.setHeight(bounds.getY());
onChanged(true);
}
}
}
package speiger.src.coreengine.rendering.gui.components;
import java.util.function.Consumer;
import java.util.function.ObjIntConsumer;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.math.misc.FacingList;
import speiger.src.coreengine.math.value.IValue;
import speiger.src.coreengine.math.value.LiniarValue;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.math.vector.ints.Vec2i;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.components.icon.CrossIcon;
import speiger.src.coreengine.rendering.gui.components.icon.LineIcon;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.utils.Cursor;
import speiger.src.coreengine.utils.functions.ConsumerConverter;
import speiger.src.coreengine.utils.helpers.InternalThreadPools;
import speiger.src.coreengine.utils.io.GameLog;
public class WindowComponent extends PanelComponent implements IButtonComponent, ObjIntConsumer<GuiComponent>
{
public static final Vec2f DEFAULT_MINIMUM_BOUNDS = Vec2f.of(75F, 7.5F);
public static final int FLAG_MINIMIZED = 1 << 20;
public static final int FLAG_RESIZEABLE = 1 << 21;
public static final int FLAG_MOVEABLE = 1 << 22;
public static final int FLAG_RESIZEABLE_HORIZONTAL = 1 << 23;
public static final int FLAG_RESIZEABLE_VERTICAL = 1 << 24;
public static final int FLAG_RESIZE_INVERT = 1 << 25;
public static final int WINDOW_FLAG_CLOSEABLE = 1;
public static final int WINDOW_FLAG_MINIMIZEABLE = 2;
public static final int WINDOW_FLAGS = WINDOW_FLAG_CLOSEABLE | WINDOW_FLAG_MINIMIZEABLE;
public static final int DEFAULT_FLAGS = WINDOW_FLAGS | FLAG_RESIZEABLE | FLAG_MOVEABLE;
public static final int FIXED_SIZE_WINDOW = WINDOW_FLAGS | FLAG_MOVEABLE;
public static final int FIXED_SIZE_POPUP = WINDOW_FLAG_CLOSEABLE | FLAG_MOVEABLE;
public static final int DYNAMIC_POPUP = FIXED_SIZE_POPUP | FLAG_RESIZEABLE;
public static final int UNCLOSEABLE_WINDOW = WINDOW_FLAG_MINIMIZEABLE | FLAG_RESIZEABLE | FLAG_MOVEABLE;
public static final int SUB_WINDOW = WINDOW_FLAG_MINIMIZEABLE | FLAG_RESIZEABLE | FLAG_RESIZE_INVERT;
final int flags;
FacingList facing = null;
String name;
int color = ColorUtils.WINDOW_DEFAULT_BACKGROUND;
Vec2f lastSize = Vec2f.mutable();
Vec2i lastClick = Vec2i.mutable();
IValue animation = null;
protected final Consumer<GuiComponent> closeListener = new ConsumerConverter<GuiComponent>(0, this);
protected final Consumer<GuiComponent> minimizedListener = new ConsumerConverter<GuiComponent>(2, this);
public WindowComponent(float x, float y, float width, float height, int flags, String name)
{
super(x, y, width, height);
this.name = name;
this.flags = flags & WINDOW_FLAGS;
setFlag(flags &= ~(WINDOW_FLAGS));
setFlag(FLAG_RESIZEABLE_HORIZONTAL | FLAG_RESIZEABLE_VERTICAL);
lastSize.set(getBox().getBaseWidth(), getBox().getBaseHeight());
}
@Override
public void init()
{
super.init();
LabelComponent label = new LabelComponent(name, ColorUtils.DARK_GRAY);
label.getText().setTextScale(0.4F).horizontal(Align.LEFT_TOP).singleLine(true);
addChild(label, new Constrains(null, null, new ParentConstrain(), new PixelConstrain(7.5F)));
float offset = 9F;
if((flags & WINDOW_FLAG_CLOSEABLE) != 0)
{
addChild(new IconButtonComponent(0F, 0F, 7.5F, 7.5F, ColorUtils.RED, new CrossIcon(ColorUtils.WHITE).setPadding(2.5F, 2F)).onAction(new ConsumerConverter<>(0, this)).setZOffset(0.001F), new Constrains(new PixelConstrain(offset).setInverted(), null, null, null));
offset += 7.5F;
}
if((flags & WINDOW_FLAG_MINIMIZEABLE) != 0)
{
addChild(new IconButtonComponent(0F, 0F, 7.5F, 7.5F, ColorUtils.GRAY, new LineIcon(ColorUtils.WHITE, 0.7F, 0.25F)).onAction(new ConsumerConverter<>(1, this)).setZOffset(0.001F), new Constrains(new PixelConstrain(offset).setInverted(), null, null, null));
}
if(canMoveIntoForground())
{
setFlag(FLAG_RENDER_ORDER);
}
}
protected void updateMinizedState(boolean value)
{
if(setFlag(FLAG_MINIMIZED, value))
{
onChanged(false);
}
}
public final WindowComponent setMinimized(boolean value)
{
if((flags & WINDOW_FLAG_MINIMIZEABLE) != 0 && setFlag(FLAG_MINIMIZED, value))
{
if(value)
{
Vec2f last = InternalThreadPools.VEC2F.get().set(lastSize);
bounds(last.getX(), isFlagSet(FLAG_MINIMIZED) ? getMinimizedY() : last.getY());
lastSize.set(last);
InternalThreadPools.VEC2F.accept(last.negate());
}
else bounds(lastSize.getX(), lastSize.getY());
onChanged(false);
}
return this;
}
public final boolean isMinimized()
{
return isFlagSet(FLAG_MINIMIZED);
}
public Vec2f getMinimumBounds()
{
return DEFAULT_MINIMUM_BOUNDS;
}
public float getMinimizedY()
{
return 7.5F;
}
public WindowComponent setColor(int color)
{
this.color = color;
return this;
}
@Override
public void calculateActualBounds(float[] area, boolean start)
{
if(animation != null)
{
float scale = getBox().getScale();
area[0] = Math.min(area[0], getBox().getMinX());
area[1] = Math.min(area[1], getBox().getMinY());
area[2] = Math.max(area[2], lastSize.getX() * scale);
area[3] = Math.max(area[3], animation.get(getMinimizedY(), lastSize.getY()) * scale);
return;
}
super.calculateActualBounds(area, start);
}
@Override
protected void updateState()
{
if(animation == null)
{
if(isFlagSet(FLAG_MINIMIZED))
{
lastSize.setX(getBox().getBaseWidth());
return;
}
lastSize.set(getBox().getBaseWidth(), getBox().getBaseHeight());
}
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
if(animation != null)
{
animation.update(particalTicks);
if(animation.isDone())
{
if(animation.get() < 0.1F)
{
updateMinizedState(true);
}
Vec2f last = InternalThreadPools.VEC2F.get().set(lastSize);
bounds(last.getX(), isFlagSet(FLAG_MINIMIZED) ? getMinimizedY() : last.getY());
lastSize.set(last);
InternalThreadPools.VEC2F.accept(last.negate());
animation = null;
}
notifyListeners(LISTENER_ON_CHANGE);
}
else if(isFlagSet(FLAG_RESIZEABLE) && !isOverChild(mouseX, mouseY) && !getGui().hasComponentInTheWay(getTopComponent(), mouseX, mouseY))
{
FacingList list = getBox().isColiding(mouseX, mouseY) ? getBox().getColidingBorder(mouseX, mouseY, 2F) : null;
if(list != null)
{
if(isFlagNotSet(FLAG_RESIZEABLE_HORIZONTAL)) list = list.remove(FacingList.HORIZONTAL);
if(isFlagNotSet(FLAG_RESIZEABLE_VERTICAL)) list = list.remove(FacingList.VERTICAL);
bindCursor(list.containsAny(FacingList.VERTICAL) && isFlagNotSet(FLAG_MINIMIZED) ? Cursor.CURSOR_VRESIZE : (list.containsAny(FacingList.HORIZONTAL) ? Cursor.CURSOR_HRESIZE : null));
}
}
if(isPopup() && !hasChildPopups() && !getGui().isComponentInFront(this))
{
requestFocus();
}
return true;
}
@Override
protected void preRender()
{
if(animation != null)
{
float scale = getBox().getScale();
enableScissors(getBox().getMinX(), getBox().getMinY(), lastSize.getX() * scale, animation.get(getMinimizedY(), lastSize.getY()) * scale);
}
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
getRenderer().drawQuad(getBox(), color);
return true;
}
@Override
protected void postRender()
{
if(animation != null)
{
disableScissors();
}
}
@Override
public void accept(GuiComponent value, int index)
{
switch(index)
{
case 0:
getGui().removeComponent(this);
break;
case 1:
if(animation != null || (flags & WINDOW_FLAG_MINIMIZEABLE) == 0)
{
break;
}
animation = (isMinimized() ? new LiniarValue(1F, 0F, 1F) : new LiniarValue(1F, 1F, 0F)).setSmooth();
if(isMinimized())
{
bounds(lastSize.getX(), lastSize.getY());
}
updateMinizedState(false);
break;
case 2:
value.setVisible(!isMinimized());
break;
}
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
if(getGui().hasComponentInTheWay(getTopComponent(), mouseX, mouseY))
{
return false;
}
facing = getBox().getColidingBorder(mouseX, mouseY, 2F);
lastClick.set(mouseX, mouseY);
if(facing != null)
{
GameLog.info("Testing: "+facing.getCode());
if(isFlagNotSet(FLAG_RESIZEABLE_HORIZONTAL)) facing = facing.remove(FacingList.HORIZONTAL);
if(isFlagNotSet(FLAG_RESIZEABLE_VERTICAL)) facing = facing.remove(FacingList.VERTICAL);
if(isOverChild(mouseX, mouseY) && facing.isEmpty())
{
facing = null;
return false;
}
return true;
}
return false;
}
@Override
public boolean onDrag(int mouseX, int mouseY)
{
if(facing != null)
{
if(facing.isEmpty() && isFlagSet(FLAG_MOVEABLE))
{
move(mouseX - lastClick.getX(), mouseY - lastClick.getY());
}
else if(!facing.isEmpty() && isFlagSet(FLAG_RESIZEABLE))
{
float scale = getBox().getScale();
float xChange = (mouseX - lastClick.getX()) * (facing.containsAny(FacingList.HORIZONTAL) ? 1F : 0F);
float yChange = (mouseY - lastClick.getY()) * (facing.containsAny(FacingList.VERTICAL) ? 1F : 0F);
if(isFlagSet(FLAG_RESIZE_INVERT))
{
xChange *= -1F;
yChange *= -1F;
}
setMassChanging();
if(facing.contains(Facing.NORTH) && isFlagNotSet(FLAG_MINIMIZED))
{
resize(0F, -(yChange / scale));
move(0F, yChange);
}
else if(facing.contains(Facing.SOUTH) && isFlagNotSet(FLAG_MINIMIZED))
{
resize(0F, yChange / scale);
}
if(facing.contains(Facing.WEST))
{
resize(-(xChange / scale) - 1F, 0F);
move(xChange, 0F);
}
else if(facing.contains(Facing.EAST))
{
resize(xChange / scale, 0F);
}
ensureMinimumBounds();
finishMassChanging();
if(xChange > 0F || yChange > 0F)
{
onChanged(true);
}
}
lastClick.set(mouseX, mouseY);
return true;
}
return false;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
facing = null;
}
@Override
public boolean canMoveIntoForground()
{
return true;
}
@Override
public void onFocusLost()
{
facing = null;
}
protected void ensureMinimumBounds()
{
IGuiBox box = getBox();
Vec2f bounds = getMinimumBounds();
if(box.getBaseWidth() < bounds.getX())
{
box.setWidth(bounds.getX());
onChanged(true);
}
if(box.getBaseHeight() < bounds.getY())
{
box.setHeight(bounds.getY());
onChanged(true);
}
}
}

View File

@ -1,84 +1,84 @@
package speiger.src.coreengine.rendering.gui.components.layouts;
import java.util.List;
import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
public class VerticalLayout implements Consumer<GuiComponent>
{
GuiComponent parent;
List<GuiComponent> components = new ObjectArrayList<>();
IGuiBox box;
float padding;
boolean changing = false;
public VerticalLayout(List<GuiComponent> components, IGuiBox box, float padding)
{
this.components.addAll(components);
for(int i = 0;i<components.size();i++)
{
components.get(i).addChangeListener(this).addCloseListener(this::removeComponent);
}
this.box = box;
this.padding = padding;
}
public VerticalLayout(IGuiBox box, float padding)
{
this.box = box;
this.padding = padding;
}
public void setParent(GuiComponent parent)
{
this.parent = parent;
}
public <T extends GuiComponent> T addComponent(T gui)
{
components.add(gui);
gui.addChangeListener(this);
gui.addCloseListener(this::removeComponent);
accept(null);
return gui;
}
public void removeComponent(GuiComponent gui)
{
if(components.remove(gui))
{
gui.removeChangeListener(this);
gui.removeCloseListener(this::removeComponent);
accept(null);
}
}
@Override
public void accept(GuiComponent t)
{
if(changing) return;
changing = true;
float minX = box.getBaseX();
float minY = box.getBaseY();
float currentY = 0F;
for(int i = 0;i<components.size();i++)
{
GuiComponent component = components.get(i);
component.setMassChanging();
float[] bounds = new float[4];
component.calculateActualBounds(bounds, true);
float height = (bounds[3] - bounds[1]) + padding;
component.set(minX, minY + currentY);
currentY += height;
component.finishMassChanging(true);
}
if(parent != null)
{
parent.onChanged(false);
}
changing = false;
}
}
package speiger.src.coreengine.rendering.gui.components.layouts;
import java.util.List;
import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
public class VerticalLayout implements Consumer<GuiComponent>
{
GuiComponent parent;
List<GuiComponent> components = new ObjectArrayList<>();
IGuiBox box;
float padding;
boolean changing = false;
public VerticalLayout(List<GuiComponent> components, IGuiBox box, float padding)
{
this.components.addAll(components);
for(int i = 0;i<components.size();i++)
{
components.get(i).onChange(this).onClose(this::removeComponent);
}
this.box = box;
this.padding = padding;
}
public VerticalLayout(IGuiBox box, float padding)
{
this.box = box;
this.padding = padding;
}
public void setParent(GuiComponent parent)
{
this.parent = parent;
}
public <T extends GuiComponent> T addComponent(T gui)
{
components.add(gui);
gui.onChange(this);
gui.onClose(this::removeComponent);
accept(null);
return gui;
}
public void removeComponent(GuiComponent gui)
{
if(components.remove(gui))
{
gui.removeChangeListener(this);
gui.removeCloseListener(this::removeComponent);
accept(null);
}
}
@Override
public void accept(GuiComponent t)
{
if(changing) return;
changing = true;
float minX = box.getBaseX();
float minY = box.getBaseY();
float currentY = 0F;
for(int i = 0;i<components.size();i++)
{
GuiComponent component = components.get(i);
component.setMassChanging();
float[] bounds = new float[4];
component.calculateActualBounds(bounds, true);
float height = (bounds[3] - bounds[1]) + padding;
component.set(minX, minY + currentY);
currentY += height;
component.finishMassChanging(true);
}
if(parent != null)
{
parent.onChanged(false);
}
changing = false;
}
}

View File

@ -1,102 +1,102 @@
package speiger.src.coreengine.rendering.gui.components.menu;
import java.util.List;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.MenuConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
public class MenuBarComponent extends GuiComponent
{
int color;
List<MenuItemComponent> menuItems = new ObjectArrayList<MenuItemComponent>();
float scale = 1F;
public MenuBarComponent(int color)
{
super(0F, 0F, 0F, 0F);
this.color = color;
}
public MenuBarComponent(float x, float y, float width, float height, int color)
{
super(x, y, width, height);
this.color = color;
}
@Override
public void init()
{
}
public MenuBarComponent setTextScale(float scale)
{
if(this.scale != scale)
{
this.scale = scale;
for(int i = 0,m=menuItems.size();i<m;i++)
{
menuItems.get(i).setTextScale(scale);
}
}
return this;
}
public MenuItemComponent addMenuItem(String name)
{
return addMenuItem(new MenuItemComponent(name));
}
public MenuItemComponent addText(String name)
{
return addMenuItem(new MenuTextComponent(name)).cast();
}
public MenuCheckBoxComponent addCheckBox(String name)
{
return addMenuItem(new MenuCheckBoxComponent(name)).cast();
}
public MenuCheckBoxComponent addCheckBox(String name, boolean defaultValue)
{
return addMenuItem(new MenuCheckBoxComponent(name, defaultValue)).cast();
}
public MenuComponent addMenu(String name)
{
return addMenuItem(new MenuComponent(name)).addUserActionListener(this::closeMenus).cast();
}
public MenuItemComponent addMenuItem(MenuItemComponent item)
{
menuItems.add(item);
item.setMenuColor(color);
addChild(item, new Constrains(new MenuConstrain<MenuItemComponent>(menuItems), new PixelConstrain(), item.createWidthConstriain(), new ParentConstrain()));
item.setZOffset(0.3F);
item.setTextScale(scale);
item.onChanged(false);
return item;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
getRenderer().drawQuad(getBox(), color);
return true;
}
protected void closeMenus(GuiComponent owner)
{
for(int i = 0,m=menuItems.size();i<m;i++)
{
MenuItemComponent comp = menuItems.get(i);
if(comp != owner && comp instanceof MenuComponent)
{
((MenuComponent)comp).setOpen(false);
}
}
}
}
package speiger.src.coreengine.rendering.gui.components.menu;
import java.util.List;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.MenuConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
public class MenuBarComponent extends GuiComponent
{
int color;
List<MenuItemComponent> menuItems = new ObjectArrayList<MenuItemComponent>();
float scale = 1F;
public MenuBarComponent(int color)
{
super(0F, 0F, 0F, 0F);
this.color = color;
}
public MenuBarComponent(float x, float y, float width, float height, int color)
{
super(x, y, width, height);
this.color = color;
}
@Override
public void init()
{
}
public MenuBarComponent setTextScale(float scale)
{
if(this.scale != scale)
{
this.scale = scale;
for(int i = 0,m=menuItems.size();i<m;i++)
{
menuItems.get(i).setTextScale(scale);
}
}
return this;
}
public MenuItemComponent addMenuItem(String name)
{
return addMenuItem(new MenuItemComponent(name));
}
public MenuItemComponent addText(String name)
{
return addMenuItem(new MenuTextComponent(name)).cast();
}
public MenuCheckBoxComponent addCheckBox(String name)
{
return addMenuItem(new MenuCheckBoxComponent(name)).cast();
}
public MenuCheckBoxComponent addCheckBox(String name, boolean defaultValue)
{
return addMenuItem(new MenuCheckBoxComponent(name, defaultValue)).cast();
}
public MenuComponent addMenu(String name)
{
return addMenuItem(new MenuComponent(name)).onAction(this::closeMenus).cast();
}
public MenuItemComponent addMenuItem(MenuItemComponent item)
{
menuItems.add(item);
item.setMenuColor(color);
addChild(item, new Constrains(new MenuConstrain<MenuItemComponent>(menuItems), new PixelConstrain(), item.createWidthConstriain(), new ParentConstrain()));
item.setZOffset(0.3F);
item.setTextScale(scale);
item.onChanged(false);
return item;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
getRenderer().drawQuad(getBox(), color);
return true;
}
protected void closeMenus(GuiComponent owner)
{
for(int i = 0,m=menuItems.size();i<m;i++)
{
MenuItemComponent comp = menuItems.get(i);
if(comp != owner && comp instanceof MenuComponent)
{
((MenuComponent)comp).setOpen(false);
}
}
}
}

View File

@ -1,126 +1,126 @@
package speiger.src.coreengine.rendering.gui.components.menu;
import speiger.src.coreengine.rendering.gui.components.misc.ICheckBox;
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
public class MenuCheckBoxComponent extends MenuItemComponent implements ICheckBox<MenuCheckBoxComponent>
{
public static final int FLAG_CHECKED = 1 << 21;
RenderBuffer buffer;
public MenuCheckBoxComponent(String name)
{
super(name);
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
}
public MenuCheckBoxComponent(String name, boolean checked)
{
super(name);
setFlag(FLAG_CHECKED, checked);
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
}
public MenuCheckBoxComponent(float x, float y, float width, float height, String name)
{
super(x, y, width, height, name);
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
}
public MenuCheckBoxComponent(float x, float y, float width, float height, String name, boolean checked)
{
super(x, y, width, height, name);
setFlag(FLAG_CHECKED, checked);
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
}
@Override
public void init()
{
addChild(text, new Constrains(new PixelConstrain(getBox().getHeight() + 1F), new ParentConstrain(), new DynamicConstrain(() -> text.getMetadata().getMaxWidth() + 0.5F), new ParentConstrain()));
addCloseListener(buffer = getRenderer().createBuffer());
}
@Override
protected void repaint()
{
float width = getBox().getHeight();
float height = getBox().getHeight();
buffer.clear();
UIShapes.createCross(buffer, width, height, (width / 3.3F), (height / 5F), color);
UIShapes.createCross(buffer, width, height, (width / 5F), (height / 10F), color);
}
@Override
protected Constrain createWidthConstriain()
{
return new DynamicConstrain(() -> text.getMetadata().getMaxWidth() + getBox().getHeight() + 3F);
}
@Override
public final boolean isChecked()
{
return isFlagSet(FLAG_CHECKED);
}
@Override
public final MenuCheckBoxComponent setChecked(boolean value)
{
setFlag(FLAG_CHECKED, value);
return this;
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brightness = getActiveBrightness();
float height = getBox().getHeight();
float centerX = getBox().getMinX(height * 0.5F);
float centerY = getBox().getMinY(height * 0.5F);
getRenderer().setBrightness(brightness * 0.85F).drawQuad(getBox().getMinX(0.2F), getBox().getMinY(), getBox().getMinX(height + 0.2F), getBox().getMinY(height), color).setBrightness(brightness * 0.75F).drawFrame(getBox().getMinX(0.2F), getBox().getMinY(), getBox().getMinX(height + 0.2F), getBox().getMinY(height), color).translate(centerX, centerY);
if(isChecked())
{
getRenderer().setBrightness(brightness * 0.7F).translate(0, 0, 0.001F).drawBuffers(buffer.selectionIterator(1), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.001F);
}
if(isHovered(mouseX, mouseY))
{
getRenderer().setBrightness(brightness * 1.3F).translate(0, 0, 0.002F).drawBuffers(buffer.selectionIterator(0), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.002F);
}
float maxX = Math.min(boxWidth, getBox().getMaxX());
getRenderer().setBrightness(1F).translate(-centerX, -centerY).drawQuad(getBox().getMinX(height), getBox().getMinY(), getBox().getMinX(maxX), getBox().getMaxY(), color).setBrightness(brightness * 0.75F).drawFrame(getBox().getMinX(height), getBox().getMinY(), getBox().getMinX(maxX), getBox().getMaxY(), color);
return true;
}
protected boolean isCheckBoxHovered(int mouseX, int mouseY)
{
float height = getBox().getHeight();
return getBox().getMinX() <= mouseX && getBox().getMinX(height) >= mouseX && getBox().getMinY() <= mouseY && getBox().getMinY(height) >= mouseY && getGui().hasComponentInTheWay(this, mouseX, mouseY);
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
return true;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
setFlag(FLAG_CHECKED, !isFlagSet(FLAG_CHECKED));
notifyListeners(LISTENER_USER_ACTION);
}
@Override
protected boolean onUserKey()
{
setFlag(FLAG_CHECKED, !isFlagSet(FLAG_CHECKED));
notifyListeners(LISTENER_USER_ACTION);
return true;
}
}
package speiger.src.coreengine.rendering.gui.components.menu;
import speiger.src.coreengine.rendering.gui.components.misc.ICheckBox;
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
public class MenuCheckBoxComponent extends MenuItemComponent implements ICheckBox<MenuCheckBoxComponent>
{
public static final int FLAG_CHECKED = 1 << 21;
RenderBuffer buffer;
public MenuCheckBoxComponent(String name)
{
super(name);
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
}
public MenuCheckBoxComponent(String name, boolean checked)
{
super(name);
setFlag(FLAG_CHECKED, checked);
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
}
public MenuCheckBoxComponent(float x, float y, float width, float height, String name)
{
super(x, y, width, height, name);
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
}
public MenuCheckBoxComponent(float x, float y, float width, float height, String name, boolean checked)
{
super(x, y, width, height, name);
setFlag(FLAG_CHECKED, checked);
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
}
@Override
public void init()
{
addChild(text, new Constrains(new PixelConstrain(getBox().getHeight() + 1F), new ParentConstrain(), new DynamicConstrain(() -> text.getMetadata().getMaxWidth() + 0.5F), new ParentConstrain()));
onClose(buffer = getRenderer().createBuffer());
}
@Override
protected void repaint()
{
float width = getBox().getHeight();
float height = getBox().getHeight();
buffer.clear();
UIShapes.createCross(buffer, width, height, (width / 3.3F), (height / 5F), color);
UIShapes.createCross(buffer, width, height, (width / 5F), (height / 10F), color);
}
@Override
protected Constrain createWidthConstriain()
{
return new DynamicConstrain(() -> text.getMetadata().getMaxWidth() + getBox().getHeight() + 3F);
}
@Override
public final boolean isChecked()
{
return isFlagSet(FLAG_CHECKED);
}
@Override
public final MenuCheckBoxComponent setChecked(boolean value)
{
setFlag(FLAG_CHECKED, value);
return this;
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brightness = getActiveBrightness();
float height = getBox().getHeight();
float centerX = getBox().getMinX(height * 0.5F);
float centerY = getBox().getMinY(height * 0.5F);
getRenderer().setBrightness(brightness * 0.85F).drawQuad(getBox().getMinX(0.2F), getBox().getMinY(), getBox().getMinX(height + 0.2F), getBox().getMinY(height), color).setBrightness(brightness * 0.75F).drawFrame(getBox().getMinX(0.2F), getBox().getMinY(), getBox().getMinX(height + 0.2F), getBox().getMinY(height), color).translate(centerX, centerY);
if(isChecked())
{
getRenderer().setBrightness(brightness * 0.7F).translate(0, 0, 0.001F).drawBuffers(buffer.selectionIterator(1), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.001F);
}
if(isHovered(mouseX, mouseY))
{
getRenderer().setBrightness(brightness * 1.3F).translate(0, 0, 0.002F).drawBuffers(buffer.selectionIterator(0), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.002F);
}
float maxX = Math.min(boxWidth, getBox().getMaxX());
getRenderer().setBrightness(1F).translate(-centerX, -centerY).drawQuad(getBox().getMinX(height), getBox().getMinY(), getBox().getMinX(maxX), getBox().getMaxY(), color).setBrightness(brightness * 0.75F).drawFrame(getBox().getMinX(height), getBox().getMinY(), getBox().getMinX(maxX), getBox().getMaxY(), color);
return true;
}
protected boolean isCheckBoxHovered(int mouseX, int mouseY)
{
float height = getBox().getHeight();
return getBox().getMinX() <= mouseX && getBox().getMinX(height) >= mouseX && getBox().getMinY() <= mouseY && getBox().getMinY(height) >= mouseY && getGui().hasComponentInTheWay(this, mouseX, mouseY);
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
return true;
}
@Override
public void onRelease(int button, int mouseX, int mouseY)
{
setFlag(FLAG_CHECKED, !isFlagSet(FLAG_CHECKED));
notifyListeners(LISTENER_USER_ACTION);
}
@Override
protected boolean onUserKey()
{
setFlag(FLAG_CHECKED, !isFlagSet(FLAG_CHECKED));
notifyListeners(LISTENER_USER_ACTION);
return true;
}
}

View File

@ -1,318 +1,318 @@
package speiger.src.coreengine.rendering.gui.components.menu;
import java.util.List;
import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.MenuConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
public class MenuComponent extends MenuItemComponent implements Consumer<GuiComponent>
{
static final int FLAG_OPEN = 1 << 21;
static final int FLAG_SUB_MENU = 1 << 22;
List<MenuItemComponent> components = new ObjectArrayList<MenuItemComponent>();
float defaultScale = 1F;
float width = 0F;
float entryHeight = 10F;
float textScale = 1F;
long timeNotHovered = -1;
MenuComponent ownerMenu;
public MenuComponent(String name)
{
super(name);
clearFlag(FLAG_SUPPORT_BINDING);
}
public MenuComponent(float x, float y, float width, float height, String name)
{
super(x, y, width, height, name);
clearFlag(FLAG_SUPPORT_BINDING);
}
@Override
public boolean canMoveIntoForground()
{
return true;
}
public MenuComponent setHeight(float height)
{
entryHeight = height;
return this;
}
protected MenuComponent setParent(MenuComponent owner)
{
ownerMenu = owner;
return this;
}
@Override
protected void setMenuColor(int color)
{
super.setMenuColor(color);
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setMenuColor(color);
}
}
public MenuComponent setDefaultScale(float scale)
{
defaultScale = scale;
return this;
}
@Override
protected void setTextScale(float scale)
{
super.setTextScale(scale);
if(textScale != scale)
{
textScale = scale;
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setTextScale(textScale);
}
}
}
@Override
protected void setBoxWidth(float value)
{
boolean changed = boxWidth != value;
super.setBoxWidth(value);
if(changed)
{
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).onChanged(false);
}
}
}
public MenuComponent addSubMenu(String name)
{
return addMenuItem(new MenuComponent(name+" >").setIsSubMenu(true).setParent(this)).cast();
}
public MenuItemComponent addText(String name)
{
return addMenuItem(new MenuTextComponent(name)).cast();
}
public MenuItemComponent addMenuItem(String name)
{
return addMenuItem(new MenuItemComponent(name));
}
public MenuCheckBoxComponent addCheckBox(String name)
{
return addMenuItem(new MenuCheckBoxComponent(name)).cast();
}
public MenuCheckBoxComponent addCheckBox(String name, boolean value)
{
return addMenuItem(new MenuCheckBoxComponent(name, value)).cast();
}
public MenuItemComponent addMenuItem(MenuItemComponent comp)
{
components.add(comp);
comp.setScale(defaultScale);
comp.setMenuColor(color);
addChild(comp.setIgnoreBounds(true).addUserActionListener(this), createConstrains(comp)).onChanged(false);
comp.setVisible(isFlagSet(FLAG_OPEN));
comp.setTextScale(textScale);
return comp;
}
protected Constrains createConstrains(MenuItemComponent comp)
{
Constrain constraint = isFlagSet(FLAG_SUB_MENU) ? new DynamicConstrain(() -> Math.max(getBox().getBaseWidth(), boxWidth / getBox().getScale())) : new PixelConstrain();
return new Constrains(constraint, new MenuConstrain<MenuItemComponent>(components, isFlagSet(FLAG_SUB_MENU) ? MenuConstrain.DEFAULT : () -> getBox().getBaseHeight() + 0.1F).setPadding(0.01F), comp.createWidthConstriain(), new PixelConstrain(entryHeight));
}
@Override
public GuiComponent removeChild(GuiComponent comp)
{
super.removeChild(comp);
if(components.remove(comp))
{
onChanged(false);
}
return this;
}
@Override
public GuiComponent removeChildren()
{
components.clear();
return super.removeChildren();
}
public void removeElements()
{
for(MenuItemComponent comp : components)
{
super.removeChild(comp);
}
components.clear();
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
if(isSubMenu() && isVisible())
{
if(isFlagSet(FLAG_OPEN))
{
if(isMouseOver(mouseX, mouseY) || isOverChild(mouseX, mouseY))
{
timeNotHovered = -1;
return true;
}
if(timeNotHovered == -1)
{
timeNotHovered = getGlobalClock();
}
if(getGlobalClock() - timeNotHovered > 10)
{
setOpen(false);
}
return true;
}
timeNotHovered = -1;
if(isMouseOver(mouseX, mouseY) && !ownerMenu.hasOtherMenuOpen(this))
{
setOpen(true);
}
}
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brigthness = isFlagSet(FLAG_OPEN) ? 0.7F : getBrightness(mouseX, mouseY);
float minX = getBox().getMinX(0.2F);
float minY = getBox().getMinY(0.2F);
float maxX = Math.max(getBox().getMaxX(), minX + boxWidth);
float maxY = getBox().getMaxY(-0.2F);
getRenderer().setBrightness(brigthness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brigthness * 0.5F).drawFrame(minX, minY, maxX, maxY, color);
text.setBrightness(brigthness);
return true;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
if(!isSubMenu())
{
setOpen(!isFlagSet(FLAG_OPEN)).notifyListeners(LISTENER_USER_ACTION);
}
return true;
}
protected MenuComponent setIsSubMenu(boolean value)
{
if(setFlag(FLAG_SUB_MENU, value))
{
setFlag(FLAG_KEEP_MENU_OPEN, value);
for(int i = 0,m=components.size();i<m;i++)
{
MenuItemComponent comp = components.get(i);
addConstrains(comp, createConstrains(comp));
}
}
return this;
}
public boolean isSubMenu()
{
return isFlagSet(FLAG_SUB_MENU);
}
public MenuComponent setOpen(boolean open)
{
if(setFlag(FLAG_OPEN, open))
{
width = 0F;
for(int i = 0,m=components.size();i<m;i++)
{
GuiComponent comp = components.get(i);
comp.setVisible(open);
width = Math.max(width, comp.getBox().getBaseWidth());
}
width *= getBox().getScale();
width += 1F;
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setBoxWidth(width);
}
onChanged(false);
}
return this;
}
protected boolean hasOtherMenuOpen(MenuComponent other)
{
for(int i = 0,m=components.size();i<m;i++)
{
MenuItemComponent comp = components.get(i);
if(comp != other && comp instanceof MenuComponent && comp.isFlagSet(FLAG_OPEN))
{
return true;
}
}
return false;
}
@Override
protected void updateState()
{
if(isFlagSet(FLAG_OPEN) != isVisible())
{
boolean isOpen = isFlagSet(FLAG_OPEN);
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setVisible(isOpen);
}
}
}
@Override
public void onFocusLost()
{
if(!isChildFocused())
{
setOpen(false);
}
}
@Override
public void accept(GuiComponent t)
{
if(t.cast(MenuItemComponent.class).isNotClosingMenu())
{
return;
}
setOpen(false);
if(ownerMenu != null)
{
ownerMenu.accept(t);
}
}
@Override
public String toString()
{
return "Menu: "+getText().getText();
}
}
package speiger.src.coreengine.rendering.gui.components.menu;
import java.util.List;
import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.MenuConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
public class MenuComponent extends MenuItemComponent implements Consumer<GuiComponent>
{
static final int FLAG_OPEN = 1 << 21;
static final int FLAG_SUB_MENU = 1 << 22;
List<MenuItemComponent> components = new ObjectArrayList<>();
float defaultScale = 1F;
float width = 0F;
float entryHeight = 10F;
float textScale = 1F;
long timeNotHovered = -1;
MenuComponent ownerMenu;
public MenuComponent(String name)
{
super(name);
clearFlag(FLAG_SUPPORT_BINDING);
}
public MenuComponent(float x, float y, float width, float height, String name)
{
super(x, y, width, height, name);
clearFlag(FLAG_SUPPORT_BINDING);
}
@Override
public boolean canMoveIntoForground()
{
return true;
}
public MenuComponent setHeight(float height)
{
entryHeight = height;
return this;
}
protected MenuComponent setParent(MenuComponent owner)
{
ownerMenu = owner;
return this;
}
@Override
protected void setMenuColor(int color)
{
super.setMenuColor(color);
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setMenuColor(color);
}
}
public MenuComponent setDefaultScale(float scale)
{
defaultScale = scale;
return this;
}
@Override
protected void setTextScale(float scale)
{
super.setTextScale(scale);
if(textScale != scale)
{
textScale = scale;
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setTextScale(textScale);
}
}
}
@Override
protected void setBoxWidth(float value)
{
boolean changed = boxWidth != value;
super.setBoxWidth(value);
if(changed)
{
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).onChanged(false);
}
}
}
public MenuComponent addSubMenu(String name)
{
return addMenuItem(new MenuComponent(name+" >").setIsSubMenu(true).setParent(this)).cast();
}
public MenuItemComponent addText(String name)
{
return addMenuItem(new MenuTextComponent(name)).cast();
}
public MenuItemComponent addMenuItem(String name)
{
return addMenuItem(new MenuItemComponent(name));
}
public MenuCheckBoxComponent addCheckBox(String name)
{
return addMenuItem(new MenuCheckBoxComponent(name)).cast();
}
public MenuCheckBoxComponent addCheckBox(String name, boolean value)
{
return addMenuItem(new MenuCheckBoxComponent(name, value)).cast();
}
public MenuItemComponent addMenuItem(MenuItemComponent comp)
{
components.add(comp);
comp.setScale(defaultScale);
comp.setMenuColor(color);
addChild(comp.setIgnoreBounds(true).onAction(this), createConstrains(comp)).onChanged(false);
comp.setVisible(isFlagSet(FLAG_OPEN));
comp.setTextScale(textScale);
return comp;
}
protected Constrains createConstrains(MenuItemComponent comp)
{
Constrain constraint = isFlagSet(FLAG_SUB_MENU) ? new DynamicConstrain(() -> Math.max(getBox().getBaseWidth(), boxWidth / getBox().getScale())) : new PixelConstrain();
return new Constrains(constraint, new MenuConstrain<MenuItemComponent>(components, isFlagSet(FLAG_SUB_MENU) ? MenuConstrain.DEFAULT : () -> getBox().getBaseHeight() + 0.1F).setPadding(0.01F), comp.createWidthConstriain(), new PixelConstrain(entryHeight));
}
@Override
public GuiComponent removeChild(GuiComponent comp)
{
super.removeChild(comp);
if(components.remove(comp))
{
onChanged(false);
}
return this;
}
@Override
public GuiComponent removeChildren()
{
components.clear();
return super.removeChildren();
}
public void removeElements()
{
for(MenuItemComponent comp : components)
{
super.removeChild(comp);
}
components.clear();
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
if(isSubMenu() && isVisible())
{
if(isFlagSet(FLAG_OPEN))
{
if(isMouseOver(mouseX, mouseY) || isOverChild(mouseX, mouseY))
{
timeNotHovered = -1;
return true;
}
if(timeNotHovered == -1)
{
timeNotHovered = getGlobalClock();
}
if(getGlobalClock() - timeNotHovered > 10)
{
setOpen(false);
}
return true;
}
timeNotHovered = -1;
if(isMouseOver(mouseX, mouseY) && !ownerMenu.hasOtherMenuOpen(this))
{
setOpen(true);
}
}
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brigthness = isFlagSet(FLAG_OPEN) ? 0.7F : getBrightness(mouseX, mouseY);
float minX = getBox().getMinX(0.2F);
float minY = getBox().getMinY(0.2F);
float maxX = Math.max(getBox().getMaxX(), minX + boxWidth);
float maxY = getBox().getMaxY(-0.2F);
getRenderer().setBrightness(brigthness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brigthness * 0.5F).drawFrame(minX, minY, maxX, maxY, color);
text.setBrightness(brigthness);
return true;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
if(!isSubMenu())
{
setOpen(!isFlagSet(FLAG_OPEN)).notifyListeners(LISTENER_USER_ACTION);
}
return true;
}
protected MenuComponent setIsSubMenu(boolean value)
{
if(setFlag(FLAG_SUB_MENU, value))
{
setFlag(FLAG_KEEP_MENU_OPEN, value);
for(int i = 0,m=components.size();i<m;i++)
{
MenuItemComponent comp = components.get(i);
addConstrains(comp, createConstrains(comp));
}
}
return this;
}
public boolean isSubMenu()
{
return isFlagSet(FLAG_SUB_MENU);
}
public MenuComponent setOpen(boolean open)
{
if(setFlag(FLAG_OPEN, open))
{
width = 0F;
for(int i = 0,m=components.size();i<m;i++)
{
GuiComponent comp = components.get(i);
comp.setVisible(open);
width = Math.max(width, comp.getBox().getBaseWidth());
}
width *= getBox().getScale();
width += 1F;
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setBoxWidth(width);
}
onChanged(false);
}
return this;
}
protected boolean hasOtherMenuOpen(MenuComponent other)
{
for(int i = 0,m=components.size();i<m;i++)
{
MenuItemComponent comp = components.get(i);
if(comp != other && comp instanceof MenuComponent && comp.isFlagSet(FLAG_OPEN))
{
return true;
}
}
return false;
}
@Override
protected void updateState()
{
if(isFlagSet(FLAG_OPEN) != isVisible())
{
boolean isOpen = isFlagSet(FLAG_OPEN);
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setVisible(isOpen);
}
}
}
@Override
public void onFocusLost()
{
if(!isChildFocused())
{
setOpen(false);
}
}
@Override
public void accept(GuiComponent t)
{
if(t.cast(MenuItemComponent.class).isNotClosingMenu())
{
return;
}
setOpen(false);
if(ownerMenu != null)
{
ownerMenu.accept(t);
}
}
@Override
public String toString()
{
return "Menu: "+getText().getText();
}
}

View File

@ -1,118 +1,118 @@
package speiger.src.coreengine.rendering.gui.components.misc;
import java.util.List;
import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.collections.objects.utils.ObjectLists;
import speiger.src.coreengine.rendering.gui.GuiComponent;
public class CheckBoxGroup<T extends GuiComponent & ICheckBox<T>> implements Consumer<GuiComponent>
{
ObjectList<T> checkboxes = new ObjectArrayList<T>();
int selectedIndex = -1;
Runnable listener;
public CheckBoxGroup<T> setListener(Runnable listener)
{
this.listener = listener;
return this;
}
public T add(T box)
{
checkboxes.add(box);
if(box.isChecked())
{
if(selectedIndex == -1)
{
selectedIndex = checkboxes.indexOf(box);
}
else
{
box.setChecked(false);
}
}
box.addUserActionListener(this);
return box;
}
public boolean remove(T box)
{
boolean result = checkboxes.remove(box);
if(result)
{
if(box.isChecked())
{
selectedIndex = -1;
}
box.removeChangeListener(this);
}
return result;
}
public T getSelected()
{
return selectedIndex == -1 ? null : checkboxes.get(selectedIndex);
}
public boolean hasSelected()
{
return selectedIndex != -1;
}
public int getSelectedIndex()
{
return selectedIndex;
}
public List<T> getCheckBoxes()
{
return ObjectLists.unmodifiable(checkboxes);
}
public void setChecked(int selected)
{
if(selectedIndex != -1)
{
checkboxes.get(selectedIndex).setChecked(false);
}
selectedIndex = selected;
if(selectedIndex != -1)
{
checkboxes.get(selectedIndex).setChecked(true);
}
}
@Override
public void accept(GuiComponent t)
{
ICheckBox<T> box = t.tryCast(ICheckBox.class);
if(box == null)
{
return;
}
int index = checkboxes.indexOf(t);
if(index == -1)
{
return;
}
if(box.isChecked())
{
if(selectedIndex != -1)
{
checkboxes.get(selectedIndex).setChecked(false);
}
selectedIndex = index;
}
else
{
selectedIndex = -1;
}
if(listener != null)
{
listener.run();
}
}
}
package speiger.src.coreengine.rendering.gui.components.misc;
import java.util.List;
import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.collections.objects.utils.ObjectLists;
import speiger.src.coreengine.rendering.gui.GuiComponent;
public class CheckBoxGroup<T extends GuiComponent & ICheckBox<T>> implements Consumer<GuiComponent>
{
ObjectList<T> checkboxes = new ObjectArrayList<T>();
int selectedIndex = -1;
Runnable listener;
public CheckBoxGroup<T> setListener(Runnable listener)
{
this.listener = listener;
return this;
}
public T add(T box)
{
checkboxes.add(box);
if(box.isChecked())
{
if(selectedIndex == -1)
{
selectedIndex = checkboxes.indexOf(box);
}
else
{
box.setChecked(false);
}
}
box.onAction(this);
return box;
}
public boolean remove(T box)
{
boolean result = checkboxes.remove(box);
if(result)
{
if(box.isChecked())
{
selectedIndex = -1;
}
box.removeChangeListener(this);
}
return result;
}
public T getSelected()
{
return selectedIndex == -1 ? null : checkboxes.get(selectedIndex);
}
public boolean hasSelected()
{
return selectedIndex != -1;
}
public int getSelectedIndex()
{
return selectedIndex;
}
public List<T> getCheckBoxes()
{
return ObjectLists.unmodifiable(checkboxes);
}
public void setChecked(int selected)
{
if(selectedIndex != -1)
{
checkboxes.get(selectedIndex).setChecked(false);
}
selectedIndex = selected;
if(selectedIndex != -1)
{
checkboxes.get(selectedIndex).setChecked(true);
}
}
@Override
public void accept(GuiComponent t)
{
ICheckBox<T> box = t.tryCast(ICheckBox.class);
if(box == null)
{
return;
}
int index = checkboxes.indexOf(t);
if(index == -1)
{
return;
}
if(box.isChecked())
{
if(selectedIndex != -1)
{
checkboxes.get(selectedIndex).setChecked(false);
}
selectedIndex = index;
}
else
{
selectedIndex = -1;
}
if(listener != null)
{
listener.run();
}
}
}

View File

@ -1,10 +1,10 @@
package speiger.src.coreengine.rendering.gui.components.misc;
import speiger.src.coreengine.rendering.gui.GuiComponent;
public interface ICheckBox<T extends GuiComponent>
{
public boolean isChecked();
public T setChecked(boolean value);
}
package speiger.src.coreengine.rendering.gui.components.misc;
import speiger.src.coreengine.rendering.gui.GuiComponent;
public interface ICheckBox<T extends GuiComponent>
{
public boolean isChecked();
public T setChecked(boolean value);
}

View File

@ -1,223 +1,223 @@
package speiger.src.coreengine.rendering.gui.components.special;
import java.util.List;
import java.util.function.Consumer;
import org.lwjgl.glfw.GLFW;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IKeyComponent;
import speiger.src.coreengine.rendering.gui.components.ListComponent;
import speiger.src.coreengine.rendering.gui.components.ScrollBarComponent;
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
import speiger.src.coreengine.rendering.gui.components.list.TextListEntry;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
import speiger.src.coreengine.rendering.gui.renderer.IFontRenderer;
public class ConsoleComponent extends GuiComponent implements IKeyComponent
{
TextFieldComponent chat = new TextFieldComponent(ColorUtils.DARK_GRAY).setCanLoseFocus(false).setInfiniteText(true).setMaxTextLength(Integer.MAX_VALUE).setFocused(true);
ListComponent<MessageEntry> list = new ListComponent<>(ColorUtils.setA(ColorUtils.DARK_GRAY, 120), 8F);
float lastWidth = 0F;
List<ConsoleMessage> messages = new ObjectArrayList<>();
Consumer<String> listener;
int messageIterator = 0;
boolean started = false;
public ConsoleComponent()
{
this(0F, 0F, 0F, 0F);
}
public ConsoleComponent(float x, float y, float width, float height)
{
super(x, y, width, height);
}
public ConsoleComponent setListener(Consumer<String> listener)
{
this.listener = listener;
return this;
}
@Override
public void init()
{
chat.getRawText().setTextScale(0.45F);
chat.addUserActionListener(this::onEnter);
list.setSelectionMode(ListComponent.SELECTION_MODE_DISABLE);
list.setStartAtBottom(true);
addChild(chat, new Constrains(new ParentConstrain(), new ParentConstrain(12F).invert(), new ParentConstrain(), new PixelConstrain(12F)));
addChild(list, new Constrains(new ParentConstrain(), new ParentConstrain(100).invert(), new RelativeConstrain(0.8F), new PixelConstrain(88)));
}
@Override
protected void updateState()
{
float width = list.getBox().getWidth();
if(lastWidth != width)
{
lastWidth = width;
updateMessages();
}
}
protected void updateMessages()
{
list.clear();
for(int i = 0,m=messages.size();i<m;i++)
{
ConsoleMessage message = messages.get(i);
addMessage(message.getMessage(), message.getMessageId(), false);
}
}
public void toggleVisiblity()
{
setVisible(!isVisible());
chat.setFocused(isVisible());
}
private void onEnter()
{
if(!chat.isVisible())
{
chat.setText("");
return;
}
if(chat.getText().isEmpty()) return;
addMessage(chat.getText(), 0);
chat.setText("");
}
@Override
public boolean isAcceptingInput()
{
return isVisible();
}
@Override
public boolean isBlockingMovement()
{
return true;
}
@Override
public boolean onKeyPressed(int key)
{
if(key == GLFW.GLFW_KEY_UP)
{
if(messageIterator < messages.size())
{
chat.setText(messages.get((messages.size()-1 - messageIterator)).getMessage()).setCurserToEnd();
messageIterator++;
started = true;
}
return true;
}
else if(key == GLFW.GLFW_KEY_DOWN)
{
if(messageIterator > 0)
{
messageIterator--;
chat.setText(messages.get((messages.size()-1 - messageIterator)).getMessage()).setCurserToEnd();
}
else if(started)
{
chat.setText("").setCurserToEnd();
started = false;
}
return true;
}
return false;
}
public void addMessage(String text)
{
addMessage(text, 0);
}
public void addMessage(String text, int messageId)
{
addMessage(text, messageId, true);
}
private void addMessage(String text, int messageId, boolean add)
{
if(listener != null && text.startsWith("/"))
{
listener.accept(text.substring(1));
return;
}
ScrollBarComponent scroll = list.getVerticalBar();
boolean atEnd = scroll.isAtEnd();
float width = (list.getBox().getWidth() -5F) / 0.45F;
for(String s : getGui().getFont().split(text, width, IFontRenderer.SPECIAL))
{
list.add(new MessageEntry(s, messageId));
}
if(atEnd) scroll.setScrollEnd();
if(add)
{
messages.add(new ConsoleMessage(messageId, text));
messageIterator = 0;
}
}
public void clearMessages()
{
messages.clear();
list.clear();
messageIterator = 0;
}
public void removeMessage(int messageId)
{
messages.removeIf(T -> T.getMessageId() == messageId);
list.removeIf(T -> T.getMessageId() == messageId);
}
private static class ConsoleMessage
{
int messageId;
String message;
public ConsoleMessage(int messageId, String message)
{
this.messageId = messageId;
this.message = message;
}
public String getMessage()
{
return message;
}
public int getMessageId()
{
return messageId;
}
}
private static class MessageEntry extends TextListEntry
{
int messageId;
public MessageEntry(String s, int messageId)
{
super(s);
this.messageId = messageId;
setScale(0.45F);
}
public int getMessageId()
{
return messageId;
}
}
package speiger.src.coreengine.rendering.gui.components.special;
import java.util.List;
import java.util.function.Consumer;
import org.lwjgl.glfw.GLFW;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IKeyComponent;
import speiger.src.coreengine.rendering.gui.components.ListComponent;
import speiger.src.coreengine.rendering.gui.components.ScrollBarComponent;
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
import speiger.src.coreengine.rendering.gui.components.list.TextListEntry;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
import speiger.src.coreengine.rendering.gui.renderer.IFontRenderer;
public class ConsoleComponent extends GuiComponent implements IKeyComponent
{
TextFieldComponent chat = new TextFieldComponent(ColorUtils.DARK_GRAY).setCanLoseFocus(false).setInfiniteText(true).setMaxTextLength(Integer.MAX_VALUE).setFocused(true);
ListComponent<MessageEntry> list = new ListComponent<>(ColorUtils.setA(ColorUtils.DARK_GRAY, 120), 8F);
float lastWidth = 0F;
List<ConsoleMessage> messages = new ObjectArrayList<>();
Consumer<String> listener;
int messageIterator = 0;
boolean started = false;
public ConsoleComponent()
{
this(0F, 0F, 0F, 0F);
}
public ConsoleComponent(float x, float y, float width, float height)
{
super(x, y, width, height);
}
public ConsoleComponent setListener(Consumer<String> listener)
{
this.listener = listener;
return this;
}
@Override
public void init()
{
chat.getRawText().setTextScale(0.45F);
chat.onAction(this::onEnter);
list.setSelectionMode(ListComponent.SELECTION_MODE_DISABLE);
list.setStartAtBottom(true);
addChild(chat, new Constrains(new ParentConstrain(), new ParentConstrain(12F).invert(), new ParentConstrain(), new PixelConstrain(12F)));
addChild(list, new Constrains(new ParentConstrain(), new ParentConstrain(100).invert(), new RelativeConstrain(0.8F), new PixelConstrain(88)));
}
@Override
protected void updateState()
{
float width = list.getBox().getWidth();
if(lastWidth != width)
{
lastWidth = width;
updateMessages();
}
}
protected void updateMessages()
{
list.clear();
for(int i = 0,m=messages.size();i<m;i++)
{
ConsoleMessage message = messages.get(i);
addMessage(message.getMessage(), message.getMessageId(), false);
}
}
public void toggleVisiblity()
{
setVisible(!isVisible());
chat.setFocused(isVisible());
}
private void onEnter()
{
if(!chat.isVisible())
{
chat.setText("");
return;
}
if(chat.getText().isEmpty()) return;
addMessage(chat.getText(), 0);
chat.setText("");
}
@Override
public boolean isAcceptingInput()
{
return isVisible();
}
@Override
public boolean isBlockingMovement()
{
return true;
}
@Override
public boolean onKeyPressed(int key)
{
if(key == GLFW.GLFW_KEY_UP)
{
if(messageIterator < messages.size())
{
chat.setText(messages.get((messages.size()-1 - messageIterator)).getMessage()).setCurserToEnd();
messageIterator++;
started = true;
}
return true;
}
else if(key == GLFW.GLFW_KEY_DOWN)
{
if(messageIterator > 0)
{
messageIterator--;
chat.setText(messages.get((messages.size()-1 - messageIterator)).getMessage()).setCurserToEnd();
}
else if(started)
{
chat.setText("").setCurserToEnd();
started = false;
}
return true;
}
return false;
}
public void addMessage(String text)
{
addMessage(text, 0);
}
public void addMessage(String text, int messageId)
{
addMessage(text, messageId, true);
}
private void addMessage(String text, int messageId, boolean add)
{
if(listener != null && text.startsWith("/"))
{
listener.accept(text.substring(1));
return;
}
ScrollBarComponent scroll = list.getVerticalBar();
boolean atEnd = scroll.isAtEnd();
float width = (list.getBox().getWidth() -5F) / 0.45F;
for(String s : getGui().getFont().split(text, width, IFontRenderer.SPECIAL))
{
list.add(new MessageEntry(s, messageId));
}
if(atEnd) scroll.setScrollEnd();
if(add)
{
messages.add(new ConsoleMessage(messageId, text));
messageIterator = 0;
}
}
public void clearMessages()
{
messages.clear();
list.clear();
messageIterator = 0;
}
public void removeMessage(int messageId)
{
messages.removeIf(T -> T.getMessageId() == messageId);
list.removeIf(T -> T.getMessageId() == messageId);
}
private static class ConsoleMessage
{
int messageId;
String message;
public ConsoleMessage(int messageId, String message)
{
this.messageId = messageId;
this.message = message;
}
public String getMessage()
{
return message;
}
public int getMessageId()
{
return messageId;
}
}
private static class MessageEntry extends TextListEntry
{
int messageId;
public MessageEntry(String s, int messageId)
{
super(s);
this.messageId = messageId;
setScale(0.45F);
}
public int getMessageId()
{
return messageId;
}
}
}

View File

@ -1,129 +1,129 @@
package speiger.src.coreengine.rendering.gui.components.tree;
import java.util.Map;
import java.util.UUID;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiBase;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.window.debug.PieProfilerWindowComponent;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.input.Keyboard;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
public class ProfilerTreeEntry extends BaseTreeEntry
{
TextComponent text = new TextComponent().limit(false).align(Align.LEFT_TOP, Align.LEFT_TOP).special(true).setTextScale(0.4F).set(0F, 1F).cast();
IProfilerEntry entry;
public ProfilerTreeEntry(IProfilerEntry entry)
{
this.entry = entry;
}
@Override
public float getWidth()
{
return text.getMetadata().getMaxWidth();
}
@Override
public void init(GuiComponent comp, GuiBase owner)
{
super.init(comp, owner);
text.setOwner(owner);
}
@Override
public void updateState(GuiComponent comp, float scale)
{
text.setScale(scale);
}
@Override
public void onClosed()
{
text.onClosed();
}
@Override
public void onFixedUpdate()
{
if(text.length() > 0 && (Keyboard.isAltDown() || text.getGui().getGlobalClock() % 2 != 0))
{
return;
}
StringBuilder builder = new StringBuilder();
builder.append(entry.getName()).append(": ");
builder.append(getColor(entry.getMinTime())).append(getTime(entry.getMinTime())).append("§<reset>").append(" / ");
builder.append(getColor(entry.getNanoTime())).append(getTime(entry.getNanoTime())).append("§<reset>").append(" / ");
builder.append(getColor(entry.getMaxTime())).append(getTime(entry.getMaxTime())).append("§<reset>");
text.setText(builder.toString());
}
@Override
public void onRender(GuiComponent comp, boolean enabled, int mouseX, int mouseY, float particalTicks)
{
text.setEnabled(enabled).render(mouseX, mouseY, particalTicks);
}
@Override
public void collectTooltips(GuiComponent comp, int mouseX, int mouseY, float particalTicks, Map<UUID, GuiComponent> collector)
{
}
@Override
public int hashCode()
{
return entry.getPathName().hashCode();
}
@Override
public boolean equals(Object obj)
{
if(obj instanceof ProfilerTreeEntry)
{
return ((ProfilerTreeEntry)obj).entry == entry;
}
return false;
}
public String getTime(long time)
{
if(time >= 2000000L)
{
return PieProfilerWindowComponent.PERCENT_FORMAT.format(time / 1000000.0D) + "ms";
}
if(time >= 2000L)
{
return PieProfilerWindowComponent.PERCENT_FORMAT.format(time / 1000.0D) + "µs";
}
return PieProfilerWindowComponent.PERCENT_FORMAT.format(time) + "ns";
}
public String getColor(long time)
{
time /= 1000000L;
if(time < 1)
{
return "§<color="+ColorUtils.LIGHT_BLUE+">";
}
if(time >= 12)
{
return "§<color="+ColorUtils.RED+">";
}
if(time >= 5)
{
return "§<color="+ColorUtils.YELLOW+">";
}
return "§<color="+ColorUtils.GREEN+">";
}
@Override
public String toString()
{
return entry.getPathName();
}
}
package speiger.src.coreengine.rendering.gui.components.tree;
import java.util.Map;
import java.util.UUID;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiBase;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.window.debug.PieProfilerWindow;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.input.Keyboard;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
public class ProfilerTreeEntry extends BaseTreeEntry
{
TextComponent text = new TextComponent().limit(false).align(Align.LEFT_TOP, Align.LEFT_TOP).special(true).setTextScale(0.4F).set(0F, 1F).cast();
IProfilerEntry entry;
public ProfilerTreeEntry(IProfilerEntry entry)
{
this.entry = entry;
}
@Override
public float getWidth()
{
return text.getMetadata().getMaxWidth();
}
@Override
public void init(GuiComponent comp, GuiBase owner)
{
super.init(comp, owner);
text.setOwner(owner);
}
@Override
public void updateState(GuiComponent comp, float scale)
{
text.setScale(scale);
}
@Override
public void onClosed()
{
text.onClosed();
}
@Override
public void onFixedUpdate()
{
if(text.length() > 0 && (Keyboard.isAltDown() || text.getGui().getGlobalClock() % 2 != 0))
{
return;
}
StringBuilder builder = new StringBuilder();
builder.append(entry.getName()).append(": ");
builder.append(getColor(entry.getMinTime())).append(getTime(entry.getMinTime())).append("§<reset>").append(" / ");
builder.append(getColor(entry.getNanoTime())).append(getTime(entry.getNanoTime())).append("§<reset>").append(" / ");
builder.append(getColor(entry.getMaxTime())).append(getTime(entry.getMaxTime())).append("§<reset>");
text.setText(builder.toString());
}
@Override
public void onRender(GuiComponent comp, boolean enabled, int mouseX, int mouseY, float particalTicks)
{
text.setEnabled(enabled).render(mouseX, mouseY, particalTicks);
}
@Override
public void collectTooltips(GuiComponent comp, int mouseX, int mouseY, float particalTicks, Map<UUID, GuiComponent> collector)
{
}
@Override
public int hashCode()
{
return entry.getPathName().hashCode();
}
@Override
public boolean equals(Object obj)
{
if(obj instanceof ProfilerTreeEntry)
{
return ((ProfilerTreeEntry)obj).entry == entry;
}
return false;
}
public String getTime(long time)
{
if(time >= 2000000L)
{
return PieProfilerWindow.PERCENT_FORMAT.format(time / 1000000.0D) + "ms";
}
if(time >= 2000L)
{
return PieProfilerWindow.PERCENT_FORMAT.format(time / 1000.0D) + "µs";
}
return PieProfilerWindow.PERCENT_FORMAT.format(time) + "ns";
}
public String getColor(long time)
{
time /= 1000000L;
if(time < 1)
{
return "§<color="+ColorUtils.LIGHT_BLUE+">";
}
if(time >= 12)
{
return "§<color="+ColorUtils.RED+">";
}
if(time >= 5)
{
return "§<color="+ColorUtils.YELLOW+">";
}
return "§<color="+ColorUtils.GREEN+">";
}
@Override
public String toString()
{
return entry.getPathName();
}
}

View File

@ -1,153 +1,153 @@
package speiger.src.coreengine.rendering.gui.components.window.color;
import java.awt.Color;
import java.util.function.IntConsumer;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.rendering.gui.UITextures;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.GradientSliderComponent;
import speiger.src.coreengine.rendering.gui.components.SliderComponent;
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.components.icon.IIcon;
import speiger.src.coreengine.rendering.gui.components.icon.TexturedIcon;
import speiger.src.coreengine.rendering.gui.helper.box.GuiBox;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
import speiger.src.coreengine.utils.functions.Functions;
import speiger.src.coreengine.utils.helpers.InternalThreadPools;
public class ColorPickerWindowComponent extends WindowComponent
{
IntConsumer listener;
IIcon wheelIcon = new TexturedIcon(UITextures.COLOR_WHEEL);
IGuiBox wheelBox = new GuiBox(15, 10, 70, 70);
IGuiBox selectedBox = new GuiBox(5F, 94F, 50F, 10F);
int[] colors = new int[]{ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0)};
SliderComponent brightness = new GradientSliderComponent(95, 13, 17, 76, 0, 100, 0, ColorUtils.GRAY, colors[2], colors[3], Facing.NORTH, null).setScrollEffect(-1).setVertical(true);
SliderComponent saturation = new GradientSliderComponent(110, 13, 17, 76, 0, 100, 0, ColorUtils.GRAY, colors[0], colors[1], Facing.NORTH, null).setScrollEffect(-1).setVertical(true);
TextFieldComponent code = new TextFieldComponent(60, 94, 104, 20, ColorUtils.DARK_GRAY).setValidator(Functions.NUMBERS_ONLY).setMaxTextLength(8);
float[] hsv = new float[3];
IGuiBox[] colorBoxes;
ColorPool pool;
public ColorPickerWindowComponent(float x, float y, ColorPool pool, int defaultColor, IntConsumer listener, String name)
{
super(x, y, 125, 140, FIXED_SIZE_POPUP, name);
this.pool = pool;
this.listener = listener;
hsv = ColorUtils.toHue(defaultColor);
colorBoxes = new IGuiBox[Math.min(18, pool.size())];
for(int i = 0,m=colorBoxes.length;i<m;i++)
{
addBox(colorBoxes[i] = new GuiBox(5 + ((i % 9) * 12), 108 + (i >= 9 ? 12 : 0), 10, 10));
}
}
@Override
public void init()
{
super.init();
addBox(wheelBox);
addBox(selectedBox);
addChild(brightness.addChangeListener(minimizedListener).addUserActionListener(T -> setColor(hsv[0], hsv[1], T.cast(SliderComponent.class).getValue() * 0.01F)));
addChild(saturation.addChangeListener(minimizedListener).addUserActionListener(T -> setColor(hsv[0], T.cast(SliderComponent.class).getValue() * 0.01F, hsv[2])));
addChild(code.setScale(0.5F).addChangeListener(minimizedListener).addUserActionListener(T -> onTyped()));
addChild(new ButtonComponent(0F, 0F, 0F, 20F, "Select", ColorUtils.GREEN).setScale(0.4F).addUserActionListener(T -> apply()), new Constrains(null, new ParentConstrain(8F).invert(), new RelativeConstrain(0.5F / 0.4F), null));
addChild(new ButtonComponent(0F, 0F, 0F, 20F, "Cancel", ColorUtils.RED).setScale(0.4F).addUserActionListener(T -> T.getGui().removeComponent(this)), new Constrains(new RelativeConstrain(0.5F), new ParentConstrain(8F).invert(), new RelativeConstrain(0.5F / 0.4F), null));
setColor(hsv[0], hsv[1], hsv[2]);
}
@Override
public boolean isPopup()
{
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
super.renderSelf(mouseX, mouseY, particalTicks);
wheelIcon.render(getRenderer().translate(0F, 0F, 0.01F).setBrightness(hsv[1]), wheelBox);
getRenderer().setBrightness(1F);
for(int i = 0,m=colorBoxes.length;i<m;i++)
{
IGuiBox box = colorBoxes[i];
getRenderer().drawQuad(box, pool.getColor(i)).drawFrame(box, ColorUtils.DARK_GRAY);
}
getRenderer().drawQuad(selectedBox, colors[4]).drawFrame(selectedBox, ColorUtils.DARK_GRAY);
float centerX = wheelBox.getCenterX();
float centerY = wheelBox.getCenterY();
Vec2f pos = InternalThreadPools.VEC2F.get().set(centerX, centerY).add(0F, -(hsv[2] * 33F)).rotate((float)Math.toRadians(-hsv[0] * 360F), centerX, centerY);
getRenderer().drawQuad(pos.getX() - 1F, pos.getY() - 1F, pos.getX() + 1F, pos.getY() + 1, 0.1F, ColorUtils.BLACK);
InternalThreadPools.VEC2F.accept(pos);
getRenderer().translate(0F, 0F, -0.01F);
return true;
}
private void onTyped()
{
try
{
int color = Integer.decode(code.getText());
float[] hsv = Color.RGBtoHSB((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF, new float[3]);
setColor(hsv[0], hsv[1], hsv[2]);
}
catch(Exception e){}
}
public void apply()
{
pool.addColor(colors[4]);
listener.accept(colors[4]);
getGui().removeComponent(this);
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
return wheelBox.isColiding(mouseX, mouseY) ? onChanged(mouseX, mouseY) : super.onClick(button, mouseX, mouseY);
}
@Override
public boolean onDrag(int mouseX, int mouseY)
{
return super.onDrag(mouseX, mouseY) || (wheelBox.isColiding(mouseX, mouseY) ? onChanged(mouseX, mouseY) : false);
}
private boolean onChanged(int mouseX, int mouseY)
{
Vec2f pos = InternalThreadPools.VEC2F.get().set(mouseX, mouseY);
float radius = (float)pos.distanceTo(wheelBox.getCenterX(), wheelBox.getCenterY());
if(radius > 38)
{
InternalThreadPools.VEC2F.accept(pos);
return false;
}
float hue = (pos.directionAngle(wheelBox.getCenterX(), wheelBox.getCenterY()) + 180F) % 360F;
setColor(hue / 360F, hsv[1], radius / 33F);
InternalThreadPools.VEC2F.accept(pos);
return true;
}
protected void setColor(float hue, float saturation, float brightness)
{
hsv[0] = MathUtils.clamp(0F, 1F, hue);
hsv[1] = MathUtils.clamp(0F, 1F, saturation);
hsv[2] = MathUtils.clamp(0F, 1F, brightness);
colors[0] = ColorUtils.toRGB(hsv[0], 0F, 1F);
colors[1] = ColorUtils.toRGB(hsv[0], 1F, 1F);
colors[2] = ColorUtils.toRGB(hsv[0], 1F, 0F);
colors[3] = ColorUtils.toRGB(hsv[0], 1F, 1F);
colors[4] = ColorUtils.toRGB(hsv[0], hsv[1], hsv[2]);
code.setText(ColorUtils.getHTMLCode(colors[4], false));
this.brightness.setValue((int)(hsv[2] * 100F));
this.saturation.setValue((int)(hsv[1] * 100F));
}
}
package speiger.src.coreengine.rendering.gui.components.window.color;
import java.awt.Color;
import java.util.function.IntConsumer;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.rendering.gui.UITextures;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.GradientSliderComponent;
import speiger.src.coreengine.rendering.gui.components.SliderComponent;
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.components.icon.IIcon;
import speiger.src.coreengine.rendering.gui.components.icon.TexturedIcon;
import speiger.src.coreengine.rendering.gui.helper.box.GuiBox;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
import speiger.src.coreengine.utils.functions.Functions;
import speiger.src.coreengine.utils.helpers.InternalThreadPools;
public class ColorPickerWindowComponent extends WindowComponent
{
IntConsumer listener;
IIcon wheelIcon = new TexturedIcon(UITextures.COLOR_WHEEL);
IGuiBox wheelBox = new GuiBox(15, 10, 70, 70);
IGuiBox selectedBox = new GuiBox(5F, 94F, 50F, 10F);
int[] colors = new int[]{ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0)};
SliderComponent brightness = new GradientSliderComponent(95, 13, 17, 76, 0, 100, 0, ColorUtils.GRAY, colors[2], colors[3], Facing.NORTH, null).setScrollEffect(-1).setVertical(true);
SliderComponent saturation = new GradientSliderComponent(110, 13, 17, 76, 0, 100, 0, ColorUtils.GRAY, colors[0], colors[1], Facing.NORTH, null).setScrollEffect(-1).setVertical(true);
TextFieldComponent code = new TextFieldComponent(60, 94, 104, 20, ColorUtils.DARK_GRAY).setValidator(Functions.NUMBERS_ONLY).setMaxTextLength(8);
float[] hsv = new float[3];
IGuiBox[] colorBoxes;
ColorPool pool;
public ColorPickerWindowComponent(float x, float y, ColorPool pool, int defaultColor, IntConsumer listener, String name)
{
super(x, y, 125, 140, FIXED_SIZE_POPUP, name);
this.pool = pool;
this.listener = listener;
hsv = ColorUtils.toHue(defaultColor);
colorBoxes = new IGuiBox[Math.min(18, pool.size())];
for(int i = 0,m=colorBoxes.length;i<m;i++)
{
addBox(colorBoxes[i] = new GuiBox(5 + ((i % 9) * 12), 108 + (i >= 9 ? 12 : 0), 10, 10));
}
}
@Override
public void init()
{
super.init();
addBox(wheelBox);
addBox(selectedBox);
addChild(brightness.onChange(minimizedListener).onAction(T -> setColor(hsv[0], hsv[1], T.cast(SliderComponent.class).getValue() * 0.01F)));
addChild(saturation.onChange(minimizedListener).onAction(T -> setColor(hsv[0], T.cast(SliderComponent.class).getValue() * 0.01F, hsv[2])));
addChild(code.setScale(0.5F).onChange(minimizedListener).onAction(T -> onTyped()));
addChild(new ButtonComponent(0F, 0F, 0F, 20F, "Select", ColorUtils.GREEN).setScale(0.4F).onAction(T -> apply()), new Constrains(null, new ParentConstrain(8F).invert(), new RelativeConstrain(0.5F / 0.4F), null));
addChild(new ButtonComponent(0F, 0F, 0F, 20F, "Cancel", ColorUtils.RED).setScale(0.4F).onAction(T -> T.getGui().removeComponent(this)), new Constrains(new RelativeConstrain(0.5F), new ParentConstrain(8F).invert(), new RelativeConstrain(0.5F / 0.4F), null));
setColor(hsv[0], hsv[1], hsv[2]);
}
@Override
public boolean isPopup()
{
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
super.renderSelf(mouseX, mouseY, particalTicks);
wheelIcon.render(getRenderer().translate(0F, 0F, 0.01F).setBrightness(hsv[1]), wheelBox);
getRenderer().setBrightness(1F);
for(int i = 0,m=colorBoxes.length;i<m;i++)
{
IGuiBox box = colorBoxes[i];
getRenderer().drawQuad(box, pool.getColor(i)).drawFrame(box, ColorUtils.DARK_GRAY);
}
getRenderer().drawQuad(selectedBox, colors[4]).drawFrame(selectedBox, ColorUtils.DARK_GRAY);
float centerX = wheelBox.getCenterX();
float centerY = wheelBox.getCenterY();
Vec2f pos = InternalThreadPools.VEC2F.get().set(centerX, centerY).add(0F, -(hsv[2] * 33F)).rotate((float)Math.toRadians(-hsv[0] * 360F), centerX, centerY);
getRenderer().drawQuad(pos.getX() - 1F, pos.getY() - 1F, pos.getX() + 1F, pos.getY() + 1, 0.1F, ColorUtils.BLACK);
InternalThreadPools.VEC2F.accept(pos);
getRenderer().translate(0F, 0F, -0.01F);
return true;
}
private void onTyped()
{
try
{
int color = Integer.decode(code.getText());
float[] hsv = Color.RGBtoHSB((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF, new float[3]);
setColor(hsv[0], hsv[1], hsv[2]);
}
catch(Exception e){}
}
public void apply()
{
pool.addColor(colors[4]);
listener.accept(colors[4]);
getGui().removeComponent(this);
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
return wheelBox.isColiding(mouseX, mouseY) ? onChanged(mouseX, mouseY) : super.onClick(button, mouseX, mouseY);
}
@Override
public boolean onDrag(int mouseX, int mouseY)
{
return super.onDrag(mouseX, mouseY) || (wheelBox.isColiding(mouseX, mouseY) ? onChanged(mouseX, mouseY) : false);
}
private boolean onChanged(int mouseX, int mouseY)
{
Vec2f pos = InternalThreadPools.VEC2F.get().set(mouseX, mouseY);
float radius = (float)pos.distanceTo(wheelBox.getCenterX(), wheelBox.getCenterY());
if(radius > 38)
{
InternalThreadPools.VEC2F.accept(pos);
return false;
}
float hue = (pos.directionAngle(wheelBox.getCenterX(), wheelBox.getCenterY()) + 180F) % 360F;
setColor(hue / 360F, hsv[1], radius / 33F);
InternalThreadPools.VEC2F.accept(pos);
return true;
}
protected void setColor(float hue, float saturation, float brightness)
{
hsv[0] = MathUtils.clamp(0F, 1F, hue);
hsv[1] = MathUtils.clamp(0F, 1F, saturation);
hsv[2] = MathUtils.clamp(0F, 1F, brightness);
colors[0] = ColorUtils.toRGB(hsv[0], 0F, 1F);
colors[1] = ColorUtils.toRGB(hsv[0], 1F, 1F);
colors[2] = ColorUtils.toRGB(hsv[0], 1F, 0F);
colors[3] = ColorUtils.toRGB(hsv[0], 1F, 1F);
colors[4] = ColorUtils.toRGB(hsv[0], hsv[1], hsv[2]);
code.setText(ColorUtils.getHTMLCode(colors[4], false));
this.brightness.setValue((int)(hsv[2] * 100F));
this.saturation.setValue((int)(hsv[1] * 100F));
}
}

View File

@ -1,306 +1,324 @@
package speiger.src.coreengine.rendering.gui.components.window.debug;
import java.text.DecimalFormat;
import java.util.List;
import java.util.function.Supplier;
import org.lwjgl.glfw.GLFW;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.utils.ObjectLists;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.rendering.gui.GuiManager;
import speiger.src.coreengine.rendering.gui.base.IKeyComponent;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.PieComponent;
import speiger.src.coreengine.rendering.gui.components.PieComponent.IPieIndex;
import speiger.src.coreengine.rendering.gui.components.PieComponent.PieIndex;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
import speiger.src.coreengine.rendering.input.Keyboard;
import speiger.src.coreengine.utils.profiler.IProfiler;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
import speiger.src.coreengine.utils.profiler.IProfiler.ProfilerData;
public class PieProfilerWindowComponent extends WindowComponent
implements Supplier<List<IPieIndex>>, IKeyComponent
{
public static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("##0.00");
PieComponent pie = new PieComponent(127, this);
ButtonComponent[] buttons = new ButtonComponent[3];
TextComponent[] extraFeatures = new TextComponent[3];
List<TextComponent[]> entries = new ObjectArrayList<TextComponent[]>();
int textInUse = 0;
IProfiler profiler;
IProfilerEntry currentEntry;
String entryName;
List<ProfilerData> lastValues = null;
public PieProfilerWindowComponent(float x, float y, float width, float height, String name)
{
super(x, y, width, height, DEFAULT_FLAGS, name);
}
@Override
public boolean canMoveIntoForground()
{
return true;
}
@Override
public void init()
{
super.init();
addChild(pie.setAutoUpdate(true).set(0F, 5F).addChangeListener(minimizedListener), new Constrains(null, null, new ParentConstrain(), new DynamicConstrain(this::calculatePieHeight)));
buttons[0] = createButton(0, "Client");
buttons[1] = createButton(1, "GPU");
buttons[2] = createButton(2, "Server");
extraFeatures[0] = new TextComponent(0F, 0F, 18F, 5.5F).setTextScale(0.3F).setText("[0] Back").align(Align.LEFT_TOP, Align.CENTER);
extraFeatures[0].addChangeListener(T -> T.setVisible(!isMinimized() && currentEntry != null && currentEntry.getParent() != null));
addChild(extraFeatures[0], new Constrains(null, new DynamicConstrain(() -> pie.getBox().getBaseHeight() + (-5.5F)), new PixelConstrain(38).setInverted(), null));
extraFeatures[1] = new TextComponent(0F, 0F, 0F, 7F).setTextScale(0.4F).setText("Client Thread");
addChild(extraFeatures[1].addChangeListener(minimizedListener), new Constrains(null, new PixelConstrain(8F), new ParentConstrain(), null));
extraFeatures[2] = new TextComponent(0F, 0F, 0F, 6F).setTextScale(0.33F).setText("Client");
addChild(extraFeatures[2].addChangeListener(minimizedListener), new Constrains(null, new PixelConstrain(15F), new ParentConstrain(), null));
}
@Override
public void onClosed()
{
super.onClosed();
if(profiler != null)
{
profiler.disable();
profiler = null;
}
}
public PieProfilerWindowComponent setProfiler(IProfiler profiler, String root)
{
if(this.profiler != null)
{
buttons[getProfilerIndex(this.profiler)].setEnabled(true);
this.profiler.disable();
}
this.profiler = profiler;
if(profiler != null)
{
profiler.enable();
setCurrentEntry(root);
buttons[getProfilerIndex(this.profiler)].setEnabled(false);
extraFeatures[1].setText(profiler.getName());
}
return this;
}
public PieProfilerWindowComponent setCurrentEntry(String name)
{
entryName = name;
currentEntry = profiler.getEntry(name);
lastValues = null;
extraFeatures[2].setText(currentEntry == null ? "Unknown" : currentEntry.getName());
return this;
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
for(int i = 0,m=entries.size();i<m;i++)
{
TextComponent[] comp = entries.get(i);
float brightness = comp[0].isTopHovered(mouseX, mouseY) || comp[1].isTopHovered(mouseX, mouseY) || comp[2].isTopHovered(mouseX, mouseY) ? 0.7F : 1F;
comp[0].setBrightness(brightness);
comp[1].setBrightness(brightness);
comp[2].setBrightness(brightness);
}
extraFeatures[0].setBrightness(extraFeatures[0].isHovered(mouseX, mouseY) ? 0.7F : 1F);
return super.updateSelf(mouseX, mouseY, particalTicks);
}
@Override
protected boolean fixedUpdateSelf()
{
if(profiler == null)
{
return true;
}
if(currentEntry == null)
{
setCurrentEntry(entryName);
return true;
}
if(currentEntry.getNanoTime() == 0L || (Keyboard.isAltDown() && lastValues != null) || (lastValues != null && getGlobalClock() % 2 != 0))
{
return true;
}
while(entries.size() < currentEntry.getChildCount() + 1)
{
entries.add(new TextComponent[] {createComponent(0), createComponent(1), createComponent(2) });
}
boolean lastEmpty = lastValues == null;
lastValues = currentEntry.getData();
int last = textInUse;
textInUse = lastValues.size();
for(int i = 0;i < textInUse;i++)
{
ProfilerData data = lastValues.get(i);
TextComponent[] info = entries.get(i);
int color = data.getColor();
info[0].setMassChanging(TextComponent.class).textColor(color).setText("[" + (i + 1) + "] " + data.getName()).finishMassChanging();
info[1].setMassChanging(TextComponent.class).textColor(color).setText(PERCENT_FORMAT.format(data.getEffect()) + "%").finishMassChanging();
info[2].setMassChanging(TextComponent.class).textColor(color).setText(PERCENT_FORMAT.format(data.getTotalEffect()) + "%").finishMassChanging();
}
if(last != textInUse)
{
resize(0F, (textInUse - last) * 5.5F);
}
else if(lastEmpty)
{
onChanged(true);
}
return true;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
if(currentEntry != null && currentEntry.getParent() != null && extraFeatures[0].isHovered(mouseX, mouseY))
{
setCurrentEntry(currentEntry.getParent().getPathName());
}
if(lastValues != null)
{
for(int i = 0;i<textInUse;i++)
{
TextComponent[] comp = entries.get(i);
if(comp[0].isHovered(mouseX, mouseY) || comp[1].isHovered(mouseX, mouseY) || comp[2].isHovered(mouseX, mouseY))
{
String s = comp[0].getText();
s = s.substring(s.indexOf("] ")+2);
if(!s.equalsIgnoreCase("Nameless"))
{
setCurrentEntry(currentEntry.getPathName() + "/" + s);
return true;
}
return false;
}
}
}
return super.onClick(button, mouseX, mouseY);
}
@Override
public boolean isAcceptingInput()
{
return isEnabled() && isVisible() && !isMinimized() && currentEntry != null && hasFocus();
}
@Override
public boolean onKeyPressed(int key)
{
if(key == GLFW.GLFW_KEY_0 && currentEntry != null && currentEntry.getParent() != null)
{
setCurrentEntry(currentEntry.getParent().getPathName());
return true;
}
else if(key >= GLFW.GLFW_KEY_1 && key <= GLFW.GLFW_KEY_9)
{
key -= GLFW.GLFW_KEY_1;
if(key < textInUse)
{
String s = entries.get(key)[0].getText();
s = s.substring(s.indexOf("] ")+2);
if(!s.equalsIgnoreCase("Nameless"))
{
setCurrentEntry(currentEntry.getPathName() + "/" + s);
return true;
}
}
return false;
}
return false;
}
@Override
public Vec2f getMinimumBounds()
{
return Vec2f.of(80F, 80F + (textInUse * 5.5F));
}
@Override
public List<IPieIndex> get()
{
if(lastValues != null)
{
List<IPieIndex> entries = new ObjectArrayList<IPieIndex>();
for(int i = 0, m = lastValues.size();i < m;i++)
{
entries.add(new PieIndex(MathUtils.floor(lastValues.get(i).getEffect() * 1.28D), lastValues.get(i).getColor()));
}
return entries;
}
return ObjectLists.singleton(new PieIndex(pie.getMaxSteps(), ColorUtils.LIGHT_BLUE));
}
protected float calculatePieHeight()
{
return getBox().getBaseHeight() - ((textInUse * 5.5F) + 9F);
}
public IProfiler getProfiler(int index)
{
GuiManager manager = getGui().getUIManager();
switch(index)
{
case 1:
return manager.getGPUProfiler();
case 2:
return manager.getServerProfiler();
default:
return manager.getCPUProfiler();
}
}
public int getProfilerIndex(IProfiler prof)
{
GuiManager manager = getGui().getUIManager();
return manager.getGPUProfiler() == prof ? 1 : manager.getServerProfiler() == prof ? 2 : 0;
}
public static String getRoot(int index)
{
return index < 2 ? "Client" : "Server";
}
protected TextComponent createComponent(int column)
{
final int index = entries.size();
String text = column == 0 ? "[" + (entries.size() + 1) + "] Unknown" : PERCENT_FORMAT.format(0D) + "%";
TextComponent comp = new TextComponent(0F, 0F, 18F, 5.5F).setTextScale(0.3F).setText(text).align(column == 0 ? Align.LEFT_TOP : Align.RIGHT_BOTTOM, Align.CENTER);
comp.addChangeListener(T -> T.setVisible(!isMinimized() && index < textInUse));
Constrain xPos = column == 0 ? null : (column == 1 ? new PixelConstrain(38F).setInverted() : new PixelConstrain(19F).setInverted());
addChild(comp, new Constrains(xPos, new DynamicConstrain(() -> pie.getBox().getBaseHeight() + (index * 5.5F)), column == 0 ? new PixelConstrain(38).setInverted() : null, null));
return comp;
}
protected ButtonComponent createButton(int index, String name)
{
ButtonComponent button = new ButtonComponent(name, ColorUtils.GRAY);
button.getText().setTextScale(0.3F);
button.addChangeListener(minimizedListener).addUserActionListener(T -> setProfiler(getProfiler(index), getRoot(index)));
addChild(button, new Constrains(new RelativeConstrain(index * 0.3333F), new PixelConstrain(8F).setInverted(), new RelativeConstrain(0.3333F), new PixelConstrain(7F)));
return button;
}
}
package speiger.src.coreengine.rendering.gui.components.window.debug;
import java.text.DecimalFormat;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.lwjgl.glfw.GLFW;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.utils.ObjectLists;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.rendering.gui.base.IKeyComponent;
import speiger.src.coreengine.rendering.gui.components.PieComponent;
import speiger.src.coreengine.rendering.gui.components.PieComponent.IPieIndex;
import speiger.src.coreengine.rendering.gui.components.PieComponent.PieIndex;
import speiger.src.coreengine.rendering.gui.components.SingleTabPanelComponent;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.input.Keyboard;
import speiger.src.coreengine.utils.profiler.IProfiler;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
import speiger.src.coreengine.utils.profiler.IProfiler.ProfilerData;
public class PieProfilerWindow extends WindowComponent implements Supplier<List<IPieIndex>>, IKeyComponent
{
public static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("##0.00");
SingleTabPanelComponent panel = new SingleTabPanelComponent(Facing.SOUTH).onAction(this::onProfilerChanged).cast();
PieComponent pie = panel.getPanel().addChild(new PieComponent(127, this).setAutoUpdate(true), Constrains.parent(Target.WIDTH).dynamic(this::calculatePieHeight, Target.HEIGHT).build());
TextComponent[] extraFeatures = new TextComponent[] {
new TextComponent(0F, 0F, 18F, 7F),
new TextComponent(0F, 0F, 0F, 8F),
new TextComponent(0F, 8F, 0F, 7F)
};
List<TextComponent[]> entries = new ObjectArrayList<>();
List<ProfilerTab> tabs = new ObjectArrayList<>();
int previouseTab = -1;
int textInUse = 0;
IProfilerEntry currentEntry;
String entryName;
List<ProfilerData> lastValues = null;
public PieProfilerWindow(float x, float y, float width, float height, String name)
{
super(x, y, width, height, DEFAULT_FLAGS, name);
}
@Override
public boolean canMoveIntoForground()
{
return true;
}
@Override
public void init()
{
super.init();
addChild(panel.set(0F, 7.5F).onChange(minimizedListener), Constrains.parent(0.25F, Target.WIDTH).parent(4F, Target.HEIGHT).build());
extraFeatures[0].setTextScale(0.3F).setText("[0] Back").horizontal(Align.LEFT_TOP);
extraFeatures[0].onChange(T -> T.setVisible(currentEntry != null && currentEntry.getParent() != null));
panel.getPanel().addChild(extraFeatures[0], Constrains.dynamic(() -> pie.getBox().getBaseHeight() - 7F, Target.Y).invPixel(38F, Target.WIDTH).build());
panel.getPanel().addChild(extraFeatures[1].setTextScale(0.4F), Constrains.parent(0F, Target.Y).parent(Target.WIDTH).build());
panel.getPanel().addChild(extraFeatures[2].setTextScale(0.33F), Constrains.pixel(8F, Target.Y).parent(Target.WIDTH).build());
}
public PieProfilerWindow addProfiler(IProfiler profiler, String root)
{
String name = profiler.getName();
panel.addTab(name);
tabs.add(new ProfilerTab(name, profiler, root));
if(tabs.size() == 1)
{
onProfilerChanged();
}
return this;
}
protected IProfiler getActive()
{
return tabs.get(panel.getActiveIndex()).getProfiler();
}
protected void applyProfiler(boolean prev, Consumer<IProfiler> action)
{
int index = prev ? previouseTab : panel.getActiveIndex();
if(index >= 0) action.accept(tabs.get(index).getProfiler());
}
@Override
public void onClosed()
{
super.onClosed();
applyProfiler(false, IProfiler::disable);
}
protected void onProfilerChanged()
{
if(previouseTab == panel.getActiveIndex()) return;
applyProfiler(true, IProfiler::disable);
applyProfiler(false, IProfiler::enable);
previouseTab = panel.getActiveIndex();
ProfilerTab tab = tabs.get(previouseTab);
extraFeatures[1].setText(tab.getName());
setCurrentEntry(tab.getRoot());
}
public SingleTabPanelComponent getTab()
{
return panel;
}
public PieProfilerWindow setCurrentEntry(String name)
{
entryName = name;
currentEntry = getActive().getEntry(name);
lastValues = null;
extraFeatures[2].setText(currentEntry == null ? "Unknown" : currentEntry.getName());
return this;
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
for(int i = 0,m=entries.size();i<m;i++)
{
TextComponent[] comp = entries.get(i);
float brightness = comp[0].isTopHovered(mouseX, mouseY) || comp[1].isTopHovered(mouseX, mouseY) || comp[2].isTopHovered(mouseX, mouseY) ? 0.7F : 1F;
comp[0].setBrightness(brightness);
comp[1].setBrightness(brightness);
comp[2].setBrightness(brightness);
}
extraFeatures[0].setBrightness(extraFeatures[0].isHovered(mouseX, mouseY) ? 0.7F : 1F);
return super.updateSelf(mouseX, mouseY, particalTicks);
}
@Override
protected boolean fixedUpdateSelf()
{
if(panel.getActiveIndex() < 0)
{
return true;
}
if(currentEntry == null)
{
setCurrentEntry(entryName);
return true;
}
if(currentEntry.getNanoTime() == 0L || (Keyboard.isAltDown() && lastValues != null) || (lastValues != null && getGlobalClock() % 2 != 0))
{
return true;
}
while(entries.size() < currentEntry.getChildCount() + 1)
{
entries.add(new TextComponent[] {createComponent(0), createComponent(1), createComponent(2) });
}
boolean lastEmpty = lastValues == null;
lastValues = currentEntry.getData();
int last = textInUse;
textInUse = lastValues.size();
for(int i = 0;i < textInUse;i++)
{
ProfilerData data = lastValues.get(i);
TextComponent[] info = entries.get(i);
int color = data.getColor();
info[0].setMassChanging(TextComponent.class).textColor(color).setText("[" + (i + 1) + "] " + data.getName()).finishMassChanging();
info[1].setMassChanging(TextComponent.class).textColor(color).setText(PERCENT_FORMAT.format(data.getEffect()) + "%").finishMassChanging();
info[2].setMassChanging(TextComponent.class).textColor(color).setText(PERCENT_FORMAT.format(data.getTotalEffect()) + "%").finishMassChanging();
}
if(last != textInUse)
{
float diff = 80F + (textInUse * 7F) - this.getBox().getHeight();
if(diff > 0) {
resize(0F, diff);
}
onChanged(true);
}
else if(lastEmpty)
{
onChanged(true);
}
return true;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
if(super.onClick(button, mouseX, mouseY))
{
return true;
}
if(currentEntry != null && currentEntry.getParent() != null && extraFeatures[0].isHovered(mouseX, mouseY))
{
setCurrentEntry(currentEntry.getParent().getPathName());
}
if(lastValues != null)
{
for(int i = 0;i<textInUse;i++)
{
TextComponent[] comp = entries.get(i);
if(comp[0].isHovered(mouseX, mouseY) || comp[1].isHovered(mouseX, mouseY) || comp[2].isHovered(mouseX, mouseY))
{
String s = comp[0].getText();
s = s.substring(s.indexOf("] ")+2);
if(!s.equalsIgnoreCase("Nameless"))
{
setCurrentEntry(currentEntry.getPathName() + "/" + s);
return true;
}
return false;
}
}
}
return false;
}
@Override
public boolean isAcceptingInput()
{
return isEnabled() && isVisible() && !isMinimized() && currentEntry != null && hasFocus();
}
@Override
public boolean onKeyPressed(int key)
{
if(key == GLFW.GLFW_KEY_0 && currentEntry != null && currentEntry.getParent() != null)
{
setCurrentEntry(currentEntry.getParent().getPathName());
return true;
}
else if(key >= GLFW.GLFW_KEY_1 && key <= GLFW.GLFW_KEY_9)
{
key -= GLFW.GLFW_KEY_1;
if(key < textInUse)
{
String s = entries.get(key)[0].getText();
s = s.substring(s.indexOf("] ")+2);
if(!s.equalsIgnoreCase("Nameless"))
{
setCurrentEntry(currentEntry.getPathName() + "/" + s);
return true;
}
}
return false;
}
return false;
}
@Override
public Vec2f getMinimumBounds()
{
return Vec2f.of(80F, 80F + (textInUse * 7F));
}
@Override
public List<IPieIndex> get()
{
if(lastValues != null)
{
List<IPieIndex> entries = new ObjectArrayList<>();
for(int i = 0, m = lastValues.size();i < m;i++)
{
entries.add(new PieIndex(MathUtils.floor(lastValues.get(i).getEffect() * 1.28D), lastValues.get(i).getColor()));
}
return entries;
}
return ObjectLists.singleton(new PieIndex(pie.getMaxSteps(), ColorUtils.LIGHT_BLUE));
}
protected float calculatePieHeight()
{
return getBox().getBaseHeight() - ((textInUse * 7) + 17F);
}
protected TextComponent createComponent(int column)
{
final int index = entries.size();
String text = column == 0 ? "[" + (entries.size() + 1) + "] Unknown" : PERCENT_FORMAT.format(0D) + "%";
TextComponent comp = new TextComponent(0F, 0F, 18F, 7F).setTextScale(0.33F).setText(text).align(column == 0 ? Align.LEFT_TOP : Align.RIGHT_BOTTOM, Align.CENTER);
comp.onChange(T -> T.setVisible(index < textInUse));
Constrain xPos = column == 0 ? null : (column == 1 ? new PixelConstrain(38F).setInverted() : new PixelConstrain(19F).setInverted());
panel.getPanel().addChild(comp, new Constrains(xPos, new DynamicConstrain(() -> pie.getBox().getBaseHeight() + (index * 7F)), column == 0 ? new PixelConstrain(38).setInverted() : null, null));
return comp;
}
private static class ProfilerTab
{
String name;
IProfiler profiler;
String root;
public ProfilerTab(String name, IProfiler profiler, String root)
{
this.name = name;
this.profiler = profiler;
this.root = root;
}
public String getName()
{
return name;
}
public IProfiler getProfiler()
{
return profiler;
}
public String getRoot()
{
return root;
}
}
}

View File

@ -0,0 +1,216 @@
package speiger.src.coreengine.rendering.gui.components.window.debug;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.ObjIntConsumer;
import speiger.src.collections.ints.queues.IntArrayFIFOQueue;
import speiger.src.collections.ints.queues.IntPriorityQueue;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.rendering.gui.components.SingleTabPanelComponent;
import speiger.src.coreengine.rendering.gui.components.TreeComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.components.tree.ProfilerTreeEntry;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.utils.profiler.IProfiler;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
public class TreeProfilerWindow extends WindowComponent
{
IntPriorityQueue todoList = new IntArrayFIFOQueue().synchronizeQueue();
ObjIntConsumer<IProfiler> listener = (T, V) -> todoList.enqueue(V);
SingleTabPanelComponent panel = new SingleTabPanelComponent(Facing.SOUTH).onAction(this::onProfilerChanged).cast();
TreeComponent<ProfilerTreeEntry> tree = panel.addChild(new TreeComponent<>(ColorUtils.GRAY, 9F).disableBackground(true).setSelectionMode(TreeComponent.SELECTION_MODE_INTERACT).cast(), Constrains.parent(Target.WIDTH).parent(4, Target.HEIGHT).build());
List<ProfilerTab> tabs = new ObjectArrayList<>();
int previouseTab = -1;
public TreeProfilerWindow(float x, float y, float width, float height, String name)
{
super(x, y, width, height, DEFAULT_FLAGS, name);
}
public TreeProfilerWindow addProfiler(IProfiler profiler, String root)
{
panel.addTab(profiler.getName());
tabs.add(new ProfilerTab(profiler, root));
if(tabs.size() == 1)
{
onProfilerChanged();
}
return this;
}
@Override
public boolean canMoveIntoForground()
{
return true;
}
@Override
public Vec2f getMinimumBounds()
{
return Vec2f.of(100F, 50F);
}
@Override
public void init()
{
super.init();
addChild(panel.set(0F, 7.5F).onChange(minimizedListener), Constrains.parent(0.25F, Target.WIDTH).parent(4F, Target.HEIGHT).build());
}
@Override
public void onClosed()
{
super.onClosed();
applyProfiler(false, this::disable);
}
@Override
protected boolean fixedUpdateSelf()
{
ProfilerTab entry = getActiveTab();
if(entry == null)
{
todoList.clear();
return true;
}
while(!todoList.isEmpty())
{
int index = todoList.dequeue();
switch(index)
{
case 0:
addEntries(entry.getRootEntry());
break;
case 1:
tree.setTree(null);
break;
case 2:
if(tree.getTree() == null)
{
addEntries(entry.getRootEntry());
break;
}
updateChildren(entry.getRootEntry(), tree.getTree());
tree.onTreeChanged();
break;
}
}
return true;
}
protected void onProfilerChanged()
{
if(previouseTab == panel.getActiveIndex()) return;
applyProfiler(true, this::disable);
applyProfiler(false, this::enable);
previouseTab = panel.getActiveIndex();
ProfilerTab tab = tabs.get(previouseTab);
setCurrentEntry(tab.getRoot());
}
protected void enable(IProfiler profiler)
{
profiler.enable();
profiler.addListener(listener);
}
protected void disable(IProfiler profiler)
{
profiler.removeListener(listener);
profiler.disable();
}
protected void addEntries(IProfilerEntry entry)
{
if(entry == null) return;
ProfilerTreeEntry child = new ProfilerTreeEntry(entry);
for(int i = 0,m=entry.getChildCount();i<m;i++)
{
addChildren(entry.getChild(i), child);
}
tree.setTree(child);
tree.openAll();
}
public TreeProfilerWindow setCurrentEntry(String name)
{
addEntries(getActive().getEntry(name));
return this;
}
protected void updateChildren(IProfilerEntry entry, ProfilerTreeEntry tree)
{
if(entry == null || tree == null) return;
for(int i = 0,m=entry.getChildCount();i<m;i++)
{
addChildren(entry.getChild(i), tree);
}
}
protected void addChildren(IProfilerEntry entry, ProfilerTreeEntry tree)
{
if(entry == null || tree == null) return;
ProfilerTreeEntry child = new ProfilerTreeEntry(entry);
int index = tree.indexOf(child);
if(index != -1) child = (ProfilerTreeEntry)tree.getChild(index);
else tree.addChild(child);
for(int i = 0,m=entry.getChildCount();i<m;i++)
{
addChildren(entry.getChild(i), child);
}
}
protected IProfiler getActive()
{
return tabs.get(panel.getActiveIndex()).getProfiler();
}
protected ProfilerTab getActiveTab()
{
int index = panel.getActiveIndex();
return index < 0 || index >= tabs.size() ? null : tabs.get(index);
}
protected void applyProfiler(boolean prev, Consumer<IProfiler> action)
{
int index = prev ? previouseTab : panel.getActiveIndex();
if(index >= 0) action.accept(tabs.get(index).getProfiler());
}
private static class ProfilerTab
{
IProfiler profiler;
String root;
public ProfilerTab(IProfiler profiler, String root)
{
this.profiler = profiler;
this.root = root;
}
public IProfiler getProfiler()
{
return profiler;
}
public String getRoot()
{
return root;
}
public IProfilerEntry getRootEntry()
{
return profiler.getEntry(root);
}
}
}

View File

@ -1,184 +0,0 @@
package speiger.src.coreengine.rendering.gui.components.window.debug;
import java.util.function.ObjIntConsumer;
import speiger.src.collections.ints.queues.IntArrayFIFOQueue;
import speiger.src.collections.ints.queues.IntPriorityQueue;
import speiger.src.collections.ints.utils.IntPriorityQueues;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.rendering.gui.GuiManager;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.TreeComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.components.tree.ProfilerTreeEntry;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
import speiger.src.coreengine.utils.profiler.IProfiler;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
public class TreeProfilerWindowComponent extends WindowComponent
{
IntPriorityQueue todoList = IntPriorityQueues.synchronize(new IntArrayFIFOQueue());
TreeComponent<ProfilerTreeEntry> tree = new TreeComponent<ProfilerTreeEntry>(ColorUtils.GRAY, 9F).disableBackground(true).setSelectionMode(TreeComponent.SELECTION_MODE_INTERACT);
ButtonComponent[] buttons = new ButtonComponent[3];
ObjIntConsumer<IProfiler> listener = (T, V) -> todoList.enqueue(V);
IProfiler profiler;
String root;
public TreeProfilerWindowComponent(float x, float y, float width, float height, String name)
{
super(x, y, width, height, DEFAULT_FLAGS, name);
}
@Override
public boolean canMoveIntoForground()
{
return true;
}
@Override
public void init()
{
super.init();
addChild(tree.addChangeListener(minimizedListener), new Constrains(new PixelConstrain(2F), new PixelConstrain(getMinimizedY()), new ParentConstrain(1.5F), new PixelConstrain(getMinimizedY() + 8.5F).setInverted()));
buttons[0] = createButton(0, "Client");
buttons[1] = createButton(1, "GPU");
buttons[2] = createButton(2, "Server");
}
@Override
protected boolean fixedUpdateSelf()
{
while(!todoList.isEmpty())
{
int index = todoList.dequeue();
switch(index)
{
case 0:
addEntries(profiler.getEntry(root));
break;
case 1:
tree.setTree(null);
break;
case 2:
if(tree.getTree() == null)
{
addEntries(profiler.getEntry(root));
break;
}
updateChildren(profiler.getEntry(root), tree.getTree());
tree.onTreeChanged();
break;
}
}
return true;
}
public TreeProfilerWindowComponent setProfiler(IProfiler profiler, String root)
{
if(this.profiler != null)
{
buttons[getProfilerIndex(this.profiler)].setEnabled(true);
this.profiler.removeListener(listener);
this.profiler.disable();
tree.setTree(null);
}
this.profiler = profiler;
this.root = root;
if(this.profiler != null)
{
buttons[getProfilerIndex(this.profiler)].setEnabled(false);
this.profiler.enable();
this.profiler.addListener(listener);
addEntries(this.profiler.getEntry(this.root));
}
return this;
}
protected void addEntries(IProfilerEntry entry)
{
if(entry == null)
{
return;
}
ProfilerTreeEntry child = new ProfilerTreeEntry(entry);
for(int i = 0,m=entry.getChildCount();i<m;i++)
{
addChildren(entry.getChild(i), child);
}
tree.setTree(child);
tree.openAll();
}
protected void updateChildren(IProfilerEntry entry, ProfilerTreeEntry tree)
{
if(entry == null || tree == null)
{
return;
}
for(int i = 0,m=entry.getChildCount();i<m;i++)
{
addChildren(entry.getChild(i), tree);
}
}
protected void addChildren(IProfilerEntry entry, ProfilerTreeEntry tree)
{
if(entry == null || tree == null)
{
return;
}
ProfilerTreeEntry child = new ProfilerTreeEntry(entry);
int index = tree.indexOf(child);
if(index != -1)
{
child = (ProfilerTreeEntry)tree.getChild(index);
}
else
{
tree.addChild(child);
}
for(int i = 0,m=entry.getChildCount();i<m;i++)
{
addChildren(entry.getChild(i), child);
}
}
public IProfiler getProfiler(int index)
{
GuiManager manager = getGui().getUIManager();
switch(index)
{
case 1:
return manager.getGPUProfiler();
case 2:
return manager.getServerProfiler();
default:
return manager.getCPUProfiler();
}
}
public int getProfilerIndex(IProfiler prof)
{
GuiManager manager = getGui().getUIManager();
return manager.getGPUProfiler() == prof ? 1 : manager.getServerProfiler() == prof ? 2 : 0;
}
protected ButtonComponent createButton(int index, String name)
{
ButtonComponent button = new ButtonComponent(name, ColorUtils.GRAY);
button.getText().setTextScale(0.3F);
button.addChangeListener(minimizedListener).addUserActionListener(T -> setProfiler(getProfiler(index), PieProfilerWindowComponent.getRoot(index)));
addChild(button, new Constrains(new RelativeConstrain(index * 0.3333F), new PixelConstrain(8F).setInverted(), new RelativeConstrain(0.3333F), new PixelConstrain(7F)));
return button;
}
@Override
public Vec2f getMinimumBounds()
{
return Vec2f.of(100F, 50F);
}
}

View File

@ -1,60 +1,60 @@
package speiger.src.coreengine.rendering.gui.components.window.misc;
import speiger.src.collections.booleans.functions.BooleanConsumer;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
public class ChoiceComponent extends WindowComponent
{
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
ButtonComponent yesButton = new ButtonComponent("Yes", ColorUtils.GRAY);
ButtonComponent noButton = new ButtonComponent("No", ColorUtils.GRAY);
BooleanConsumer listener;
public ChoiceComponent(float width, String windowTitle, String message, BooleanConsumer listener)
{
this(0F, 0F, width, windowTitle, message, listener);
}
public ChoiceComponent(float x, float y, float width, String windowTitle, String message, BooleanConsumer listener)
{
super(x, y, width, 25F, FIXED_SIZE_POPUP, windowTitle);
this.message.setText(message);
this.listener = listener;
}
public static ChoiceComponent createChoice(float width, String windowTitle, String message, BooleanConsumer listener)
{
return new ChoiceComponent(width, windowTitle, message, listener);
}
public static ChoiceComponent createChoice(String windowTitle, String message, BooleanConsumer listener)
{
return new ChoiceComponent(150, windowTitle, message, listener);
}
@Override
public void init()
{
super.init();
yesButton.getText().setTextScale(0.5F);
noButton.getText().setTextScale(0.5F);
addChild(yesButton.addChangeListener(minimizedListener).addUserActionListener(closeListener).addUserActionListener(T -> listener.accept(true)), new Constrains(new RelativeConstrain(0F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F)));
addChild(noButton.addChangeListener(minimizedListener).addUserActionListener(closeListener).addUserActionListener(T -> listener.accept(false)), new Constrains(new RelativeConstrain(0.5F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F)));
addChild(message, new Constrains(new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message)));
getBox().setHeight(25F + message.getMetadata().getMaxHeight());
}
@Override
public boolean isPopup()
{
return true;
}
}
package speiger.src.coreengine.rendering.gui.components.window.misc;
import speiger.src.collections.booleans.functions.BooleanConsumer;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
public class ChoiceComponent extends WindowComponent
{
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
ButtonComponent yesButton = new ButtonComponent("Yes", ColorUtils.GRAY);
ButtonComponent noButton = new ButtonComponent("No", ColorUtils.GRAY);
BooleanConsumer listener;
public ChoiceComponent(float width, String windowTitle, String message, BooleanConsumer listener)
{
this(0F, 0F, width, windowTitle, message, listener);
}
public ChoiceComponent(float x, float y, float width, String windowTitle, String message, BooleanConsumer listener)
{
super(x, y, width, 25F, FIXED_SIZE_POPUP, windowTitle);
this.message.setText(message);
this.listener = listener;
}
public static ChoiceComponent createChoice(float width, String windowTitle, String message, BooleanConsumer listener)
{
return new ChoiceComponent(width, windowTitle, message, listener);
}
public static ChoiceComponent createChoice(String windowTitle, String message, BooleanConsumer listener)
{
return new ChoiceComponent(150, windowTitle, message, listener);
}
@Override
public void init()
{
super.init();
yesButton.getText().setTextScale(0.5F);
noButton.getText().setTextScale(0.5F);
addChild(yesButton.onChange(minimizedListener).onAction(closeListener).onAction(T -> listener.accept(true)), new Constrains(new RelativeConstrain(0F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F)));
addChild(noButton.onChange(minimizedListener).onAction(closeListener).onAction(T -> listener.accept(false)), new Constrains(new RelativeConstrain(0.5F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F)));
addChild(message, new Constrains(new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message)));
getBox().setHeight(25F + message.getMetadata().getMaxHeight());
}
@Override
public boolean isPopup()
{
return true;
}
}

View File

@ -1,74 +1,74 @@
package speiger.src.coreengine.rendering.gui.components.window.misc;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
public class MessageComponent extends WindowComponent
{
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
ButtonComponent resultButton = new ButtonComponent("", ColorUtils.GRAY);
public MessageComponent(float width, String windowTitle, String confirmButton, String message)
{
this(0F, 0F, width, windowTitle, confirmButton, message);
}
public MessageComponent(float x, float y, float width, String windowTitle, String confirmButton, String message)
{
super(x, y, width, 25F, FIXED_SIZE_POPUP, windowTitle);
resultButton.getText().setText(confirmButton);
this.message.setText(message);
}
public static MessageComponent createInfo(String message)
{
return new MessageComponent(150, "Info", "Ok", message);
}
public static MessageComponent createInfo(float width, String message)
{
return new MessageComponent(width, "Info", "Ok", message);
}
public static MessageComponent createWarn(String message)
{
return new MessageComponent(150, "Warn", "Ok", message);
}
public static MessageComponent createWarn(float width, String message)
{
return new MessageComponent(width, "Warn", "Ok", message);
}
public static MessageComponent createError(String message)
{
return new MessageComponent(150, "Error!", "Ok", message);
}
public static MessageComponent createError(float width, String message)
{
return new MessageComponent(width, "Error!", "Ok", message);
}
@Override
public void init()
{
super.init();
resultButton.getText().setTextScale(0.5F);
addChild(resultButton.addChangeListener(minimizedListener).addUserActionListener(closeListener), new Constrains(new ParentConstrain(), new ParentConstrain(10F).invert(), new ParentConstrain(), new PixelConstrain(10F)));
addChild(message, new Constrains(new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message)));
getBox().setHeight(25F + message.getMetadata().getMaxHeight());
}
@Override
public boolean isPopup()
{
return true;
}
}
package speiger.src.coreengine.rendering.gui.components.window.misc;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
public class MessageComponent extends WindowComponent
{
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
ButtonComponent resultButton = new ButtonComponent("", ColorUtils.GRAY);
public MessageComponent(float width, String windowTitle, String confirmButton, String message)
{
this(0F, 0F, width, windowTitle, confirmButton, message);
}
public MessageComponent(float x, float y, float width, String windowTitle, String confirmButton, String message)
{
super(x, y, width, 25F, FIXED_SIZE_POPUP, windowTitle);
resultButton.getText().setText(confirmButton);
this.message.setText(message);
}
public static MessageComponent createInfo(String message)
{
return new MessageComponent(150, "Info", "Ok", message);
}
public static MessageComponent createInfo(float width, String message)
{
return new MessageComponent(width, "Info", "Ok", message);
}
public static MessageComponent createWarn(String message)
{
return new MessageComponent(150, "Warn", "Ok", message);
}
public static MessageComponent createWarn(float width, String message)
{
return new MessageComponent(width, "Warn", "Ok", message);
}
public static MessageComponent createError(String message)
{
return new MessageComponent(150, "Error!", "Ok", message);
}
public static MessageComponent createError(float width, String message)
{
return new MessageComponent(width, "Error!", "Ok", message);
}
@Override
public void init()
{
super.init();
resultButton.getText().setTextScale(0.5F);
addChild(resultButton.onChange(minimizedListener).onAction(closeListener), new Constrains(new ParentConstrain(), new ParentConstrain(10F).invert(), new ParentConstrain(), new PixelConstrain(10F)));
addChild(message, new Constrains(new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message)));
getBox().setHeight(25F + message.getMetadata().getMaxHeight());
}
@Override
public boolean isPopup()
{
return true;
}
}

View File

@ -1,66 +1,66 @@
package speiger.src.coreengine.rendering.gui.components.window.misc;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
public class TextInputComponent extends WindowComponent
{
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
TextFieldComponent input = new TextFieldComponent(ColorUtils.GRAY).setCanLoseFocus(false).setInfiniteText(true).setMaxTextLength(Integer.MAX_VALUE).setFocused(true);
ButtonComponent confirm = new ButtonComponent("Confirm", ColorUtils.DARK_GREEN);
ButtonComponent cancel = new ButtonComponent("Cancel", ColorUtils.RED);
public TextInputComponent(float width, String name, String message)
{
this(0F, 0F, width, name, message);
}
public TextInputComponent(float x, float y, float width, String name, String message)
{
super(x, y, width, 35F, FIXED_SIZE_POPUP, name);
this.message.setText(message);
}
public TextFieldComponent getInput()
{
return input;
}
public String getText()
{
return input.getText();
}
@Override
public void init()
{
super.init();
confirm.getText().setTextScale(0.5F);
cancel.getText().setTextScale(0.5F);
input.getRawText().setTextScale(0.5F);
addChild(confirm.addChangeListener(minimizedListener).addUserActionListener(this::onListen), new RelativeConstrain(0F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F));
addChild(cancel.addChangeListener(minimizedListener).addUserActionListener(closeListener), new RelativeConstrain(0.5F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F));
addChild(message.addChangeListener(minimizedListener), new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message));
addChild(input.addChangeListener(minimizedListener).addUserActionListener(this::onListen), new PixelConstrain(10F), TextConstrain.height(message).setPadding(15F), new ParentConstrain(10F), new PixelConstrain(12F));
getBox().setHeight(45F + message.getMetadata().getMaxHeight());
}
private void onListen()
{
notifyListeners(LISTENER_USER_ACTION);
closeListener.accept(this);
}
@Override
public boolean isPopup()
{
return true;
}
}
package speiger.src.coreengine.rendering.gui.components.window.misc;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
public class TextInputComponent extends WindowComponent
{
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
TextFieldComponent input = new TextFieldComponent(ColorUtils.GRAY).setCanLoseFocus(false).setInfiniteText(true).setMaxTextLength(Integer.MAX_VALUE).setFocused(true);
ButtonComponent confirm = new ButtonComponent("Confirm", ColorUtils.DARK_GREEN);
ButtonComponent cancel = new ButtonComponent("Cancel", ColorUtils.RED);
public TextInputComponent(float width, String name, String message)
{
this(0F, 0F, width, name, message);
}
public TextInputComponent(float x, float y, float width, String name, String message)
{
super(x, y, width, 35F, FIXED_SIZE_POPUP, name);
this.message.setText(message);
}
public TextFieldComponent getInput()
{
return input;
}
public String getText()
{
return input.getText();
}
@Override
public void init()
{
super.init();
confirm.getText().setTextScale(0.5F);
cancel.getText().setTextScale(0.5F);
input.getRawText().setTextScale(0.5F);
addChild(confirm.onChange(minimizedListener).onAction(this::onListen), new RelativeConstrain(0F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F));
addChild(cancel.onChange(minimizedListener).onAction(closeListener), new RelativeConstrain(0.5F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F));
addChild(message.onChange(minimizedListener), new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message));
addChild(input.onChange(minimizedListener).onAction(this::onListen), new PixelConstrain(10F), TextConstrain.height(message).setPadding(15F), new ParentConstrain(10F), new PixelConstrain(12F));
getBox().setHeight(45F + message.getMetadata().getMaxHeight());
}
private void onListen()
{
notifyListeners(LISTENER_USER_ACTION);
closeListener.accept(this);
}
@Override
public boolean isPopup()
{
return true;
}
}

View File

@ -1,53 +1,53 @@
package speiger.src.coreengine.rendering.gui.helper.animations;
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
import speiger.src.collections.objects.utils.maps.Object2ObjectMaps;
import speiger.src.coreengine.math.value.ConstantValue;
import speiger.src.coreengine.math.value.IValue;
import speiger.src.coreengine.rendering.gui.helper.animations.Animation.AnimationListener;
public class AnimationInstance
{
Object2ObjectMap<AnimationTarget, IValue> values;
float totalProgress;
boolean reverse;
AnimationListener listener;
float progress = 0F;
public AnimationInstance(Object2ObjectMap<AnimationTarget, IValue> values, float totalProgress, boolean reverse, AnimationListener listener)
{
this.values = values;
this.totalProgress = totalProgress;
this.reverse = reverse;
this.listener = listener;
}
public void update(Animator animator, float particalTime)
{
progress += particalTime;
for(Object2ObjectMap.Entry<AnimationTarget, IValue> entry : Object2ObjectMaps.fastIterable(values))
{
entry.getKey().apply(animator, entry.getValue().update(particalTime));
}
}
public float getCurrentProgress(AnimationTarget target)
{
return values.getOrDefault(target, ConstantValue.ZERO).get();
}
public boolean isDone()
{
return reverse && progress >= totalProgress;
}
public AnimationListener getListener()
{
return listener;
}
public boolean isReverse()
{
return reverse;
}
package speiger.src.coreengine.rendering.gui.helper.animations;
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
import speiger.src.collections.objects.utils.maps.Object2ObjectMaps;
import speiger.src.coreengine.math.value.ConstantValue;
import speiger.src.coreengine.math.value.IValue;
import speiger.src.coreengine.rendering.gui.helper.animations.Animation.AnimationListener;
public class AnimationInstance
{
Object2ObjectMap<AnimationTarget, IValue> values;
float totalProgress;
boolean reverse;
AnimationListener listener;
float progress = 0F;
public AnimationInstance(Object2ObjectMap<AnimationTarget, IValue> values, float totalProgress, boolean reverse, AnimationListener listener)
{
this.values = values;
this.totalProgress = totalProgress;
this.reverse = reverse;
this.listener = listener;
}
public void update(Animator animator, float particalTime)
{
progress += particalTime;
for(Object2ObjectMap.Entry<AnimationTarget, IValue> entry : Object2ObjectMaps.fastIterable(values))
{
entry.getKey().apply(animator, entry.getValue().update(particalTime));
}
}
public float getCurrentProgress(AnimationTarget target)
{
return values.getOrDefault(target, ConstantValue.ZERO).get();
}
public boolean isDone()
{
return reverse && progress >= totalProgress;
}
public AnimationListener getListener()
{
return listener;
}
public boolean isReverse()
{
return reverse;
}
}

View File

@ -1,125 +1,131 @@
package speiger.src.coreengine.rendering.gui.helper.constrains;
import java.util.function.BooleanSupplier;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
import speiger.src.coreengine.utils.functions.FloatSupplier;
public class Constrains
{
Constrain[] constrains = new Constrain[4];
private Constrains(Constrain[] array)
{
System.arraycopy(array, 0, constrains, 0, 4);
}
public Constrains(Constrain xPos, Constrain yPos, Constrain width, Constrain height)
{
constrains[0] = xPos;
constrains[1] = yPos;
constrains[2] = width;
constrains[3] = height;
}
public void setOwner(GuiComponent owner, GuiComponent parent)
{
for(int i = 0;i<4;i++) {
if(constrains[i] != null) {
constrains[i].setComponents(owner, parent, Target.by(i));
}
}
}
public void onComponentChanged()
{
for(int i = 0;i<4;i++) {
if(constrains[i] != null) constrains[i].apply();
}
}
public static Constrains parent() { return new Constrains(new ParentConstrain(), new ParentConstrain(), new ParentConstrain(), new ParentConstrain()); }
public static Constrains parent(float padding) { return new Constrains(new ParentConstrain(padding), new ParentConstrain(padding), new ParentConstrain(padding), new ParentConstrain(padding)); }
public static Constrains parent(float xPadding, float yPadding) { return new Constrains(new ParentConstrain(xPadding), new ParentConstrain(yPadding), new ParentConstrain(xPadding), new ParentConstrain(yPadding)); }
public static Constrains parent(float x, float y, float width, float height) { return new Constrains(new ParentConstrain(x), new ParentConstrain(y), new ParentConstrain(width), new ParentConstrain(height)); }
public static Constrains scrollBar(BooleanSupplier supply, boolean horizontal, float barSize) {
Constrain bounds = new ConditionalConstraint(supply, new ParentConstrain(), new ParentConstrain(barSize / 2F));
return horizontal ? new Constrains(new PixelConstrain(), new ParentConstrain(barSize).invert(), bounds, new PixelConstrain(barSize)) : new Constrains(new ParentConstrain(barSize).invert(), new PixelConstrain(), new PixelConstrain(barSize), bounds);
}
public static Constrains verticalScrollBar(BooleanSupplier supply, float offset, float barSize) { return invParent(barSize, Target.X).yPos(offset).width(barSize).height(new ConditionalConstraint(supply, new ParentConstrain(offset * 0.5F), new ParentConstrain((barSize + offset) * 0.5F))).build(); }
public static Constrains border(float size, Facing side, float offset)
{
switch(side)
{
case NORTH: return new Constrains(new ParentConstrain(), new ParentConstrain(offset), new ParentConstrain(), new PixelConstrain(size));
case EAST: return new Constrains(new ParentConstrain(size+offset).invert(), new ParentConstrain(), new PixelConstrain(size), new ParentConstrain());
case SOUTH: return new Constrains(new ParentConstrain(), new ParentConstrain(size+offset).invert(), new ParentConstrain(), new PixelConstrain(size));
case WEST: return new Constrains(new ParentConstrain(offset), new ParentConstrain(), new PixelConstrain(size), new ParentConstrain());
default: return null;
}
}
public static ConstrainBuilder xPos(Constrain xPos) { return new ConstrainBuilder().set(xPos, Target.X); }
public static ConstrainBuilder yPos(Constrain yPos) { return new ConstrainBuilder().set(yPos, Target.Y); }
public static ConstrainBuilder width(Constrain width) { return new ConstrainBuilder().set(width, Target.WIDTH); }
public static ConstrainBuilder height(Constrain height) { return new ConstrainBuilder().set(height, Target.HEIGHT); }
public static ConstrainBuilder xPos(float xPos) { return new ConstrainBuilder().set(new PixelConstrain(xPos), Target.X); }
public static ConstrainBuilder yPos(float yPos) { return new ConstrainBuilder().set(new PixelConstrain(yPos), Target.Y); }
public static ConstrainBuilder width(float width) { return new ConstrainBuilder().set(new PixelConstrain(width), Target.WIDTH); }
public static ConstrainBuilder height(float height) { return new ConstrainBuilder().set(new PixelConstrain(height), Target.HEIGHT); }
public static ConstrainBuilder xPosR(float xPos) { return new ConstrainBuilder().set(new RelativeConstrain(xPos), Target.X); }
public static ConstrainBuilder yPosR(float yPos) { return new ConstrainBuilder().set(new RelativeConstrain(yPos), Target.Y); }
public static ConstrainBuilder widthR(float width) { return new ConstrainBuilder().set(new RelativeConstrain(width), Target.WIDTH); }
public static ConstrainBuilder heightR(float height) { return new ConstrainBuilder().set(new RelativeConstrain(height), Target.HEIGHT); }
public static ConstrainBuilder parent(Target target) { return new ConstrainBuilder().set(new ParentConstrain(), target); }
public static ConstrainBuilder invParent(Target target) { return new ConstrainBuilder().set(new ParentConstrain().invert(), target); }
public static ConstrainBuilder parent(float padding, Target target) { return new ConstrainBuilder().set(new ParentConstrain(padding), target); }
public static ConstrainBuilder invParent(float padding, Target target) { return new ConstrainBuilder().set(new ParentConstrain(padding).invert(), target); }
public static ConstrainBuilder center(Target target) { return new ConstrainBuilder().set(new CenterConstrain(), target); }
public static ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return new ConstrainBuilder().set(new DynamicConstrain(provider), target); }
public static class ConstrainBuilder
{
Constrain[] constrains = new Constrain[4];
public ConstrainBuilder set(Constrain value, Target target) {
constrains[target.ordinal()] = value;
return this;
}
public ConstrainBuilder xPos(Constrain xPos) { return set(xPos, Target.X); }
public ConstrainBuilder yPos(Constrain yPos) { return set(yPos, Target.Y); }
public ConstrainBuilder width(Constrain width) { return set(width, Target.WIDTH); }
public ConstrainBuilder height(Constrain height) { return set(height, Target.HEIGHT); }
public ConstrainBuilder xPos(float xPos) { return set(new PixelConstrain(xPos), Target.X); }
public ConstrainBuilder yPos(float yPos) { return set(new PixelConstrain(yPos), Target.Y); }
public ConstrainBuilder width(float width) { return set(new PixelConstrain(width), Target.WIDTH); }
public ConstrainBuilder height(float height) { return set(new PixelConstrain(height), Target.HEIGHT); }
public ConstrainBuilder xPosR(float xPos) { return set(new RelativeConstrain(xPos), Target.X); }
public ConstrainBuilder yPosR(float yPos) { return set(new RelativeConstrain(yPos), Target.Y); }
public ConstrainBuilder widthR(float width) { return set(new RelativeConstrain(width), Target.WIDTH); }
public ConstrainBuilder heightR(float height) { return set(new RelativeConstrain(height), Target.HEIGHT); }
public ConstrainBuilder parent(Target target) { return set(new ParentConstrain(), target); }
public ConstrainBuilder invParent(Target target) { return set(new ParentConstrain().invert(), target); }
public ConstrainBuilder parent(float padding, Target target) { return set(new ParentConstrain(padding), target); }
public ConstrainBuilder invParent(float padding, Target target) { return set(new ParentConstrain(padding).invert(), target); }
public ConstrainBuilder center(Target target) { return set(new CenterConstrain(), target); }
public ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return set(new DynamicConstrain(provider), target); }
public Constrains build()
{
return new Constrains(constrains);
}
}
}
package speiger.src.coreengine.rendering.gui.helper.constrains;
import java.util.function.BooleanSupplier;
import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
import speiger.src.coreengine.utils.functions.FloatSupplier;
public class Constrains
{
Constrain[] constrains = new Constrain[4];
private Constrains(Constrain[] array)
{
System.arraycopy(array, 0, constrains, 0, 4);
}
public Constrains(Constrain xPos, Constrain yPos, Constrain width, Constrain height)
{
constrains[0] = xPos;
constrains[1] = yPos;
constrains[2] = width;
constrains[3] = height;
}
public void setOwner(GuiComponent owner, GuiComponent parent)
{
for(int i = 0;i<4;i++) {
if(constrains[i] != null) {
constrains[i].setComponents(owner, parent, Target.by(i));
}
}
}
public void onComponentChanged()
{
for(int i = 0;i<4;i++) {
if(constrains[i] != null) constrains[i].apply();
}
}
public static Constrains parent() { return new Constrains(new ParentConstrain(), new ParentConstrain(), new ParentConstrain(), new ParentConstrain()); }
public static Constrains parent(float padding) { return new Constrains(new ParentConstrain(padding), new ParentConstrain(padding), new ParentConstrain(padding), new ParentConstrain(padding)); }
public static Constrains parent(float xPadding, float yPadding) { return new Constrains(new ParentConstrain(xPadding), new ParentConstrain(yPadding), new ParentConstrain(xPadding), new ParentConstrain(yPadding)); }
public static Constrains parent(float x, float y, float width, float height) { return new Constrains(new ParentConstrain(x), new ParentConstrain(y), new ParentConstrain(width), new ParentConstrain(height)); }
public static Constrains scrollBar(BooleanSupplier supply, boolean horizontal, float barSize) {
Constrain bounds = new ConditionalConstraint(supply, new ParentConstrain(), new ParentConstrain(barSize / 2F));
return horizontal ? new Constrains(new PixelConstrain(), new ParentConstrain(barSize).invert(), bounds, new PixelConstrain(barSize)) : new Constrains(new ParentConstrain(barSize).invert(), new PixelConstrain(), new PixelConstrain(barSize), bounds);
}
public static Constrains verticalScrollBar(BooleanSupplier supply, float offset, float barSize) { return invParent(barSize, Target.X).yPos(offset).width(barSize).height(new ConditionalConstraint(supply, new ParentConstrain(offset * 0.5F), new ParentConstrain((barSize + offset) * 0.5F))).build(); }
public static Constrains border(float size, Facing side, float offset)
{
switch(side)
{
case NORTH: return new Constrains(new ParentConstrain(), new ParentConstrain(offset), new ParentConstrain(), new PixelConstrain(size));
case EAST: return new Constrains(new ParentConstrain(size+offset).invert(), new ParentConstrain(), new PixelConstrain(size), new ParentConstrain());
case SOUTH: return new Constrains(new ParentConstrain(), new ParentConstrain(size+offset).invert(), new ParentConstrain(), new PixelConstrain(size));
case WEST: return new Constrains(new ParentConstrain(offset), new ParentConstrain(), new PixelConstrain(size), new ParentConstrain());
default: return null;
}
}
public static ConstrainBuilder builder() { return new ConstrainBuilder(); };
public static ConstrainBuilder xPos(Constrain xPos) { return new ConstrainBuilder().set(xPos, Target.X); }
public static ConstrainBuilder yPos(Constrain yPos) { return new ConstrainBuilder().set(yPos, Target.Y); }
public static ConstrainBuilder width(Constrain width) { return new ConstrainBuilder().set(width, Target.WIDTH); }
public static ConstrainBuilder height(Constrain height) { return new ConstrainBuilder().set(height, Target.HEIGHT); }
public static ConstrainBuilder xPos(float xPos) { return new ConstrainBuilder().set(new PixelConstrain(xPos), Target.X); }
public static ConstrainBuilder yPos(float yPos) { return new ConstrainBuilder().set(new PixelConstrain(yPos), Target.Y); }
public static ConstrainBuilder width(float width) { return new ConstrainBuilder().set(new PixelConstrain(width), Target.WIDTH); }
public static ConstrainBuilder height(float height) { return new ConstrainBuilder().set(new PixelConstrain(height), Target.HEIGHT); }
public static ConstrainBuilder xPosR(float xPos) { return new ConstrainBuilder().set(new RelativeConstrain(xPos), Target.X); }
public static ConstrainBuilder yPosR(float yPos) { return new ConstrainBuilder().set(new RelativeConstrain(yPos), Target.Y); }
public static ConstrainBuilder widthR(float width) { return new ConstrainBuilder().set(new RelativeConstrain(width), Target.WIDTH); }
public static ConstrainBuilder heightR(float height) { return new ConstrainBuilder().set(new RelativeConstrain(height), Target.HEIGHT); }
public static ConstrainBuilder parent(Target target) { return new ConstrainBuilder().set(new ParentConstrain(), target); }
public static ConstrainBuilder invParent(Target target) { return new ConstrainBuilder().set(new ParentConstrain().invert(), target); }
public static ConstrainBuilder parent(float padding, Target target) { return new ConstrainBuilder().set(new ParentConstrain(padding), target); }
public static ConstrainBuilder invParent(float padding, Target target) { return new ConstrainBuilder().set(new ParentConstrain(padding).invert(), target); }
public static ConstrainBuilder pixel(float pixels, Target target) { return new ConstrainBuilder().set(new PixelConstrain(pixels), target); }
public static ConstrainBuilder invPixel(float pixels, Target target) { return new ConstrainBuilder().set(new PixelConstrain(pixels).setInverted(), target); }
public static ConstrainBuilder center(Target target) { return new ConstrainBuilder().set(new CenterConstrain(), target); }
public static ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return new ConstrainBuilder().set(new DynamicConstrain(provider), target); }
public static class ConstrainBuilder
{
Constrain[] constrains = new Constrain[4];
public ConstrainBuilder set(Constrain value, Target target) {
constrains[target.ordinal()] = value;
return this;
}
public ConstrainBuilder xPos(Constrain xPos) { return set(xPos, Target.X); }
public ConstrainBuilder yPos(Constrain yPos) { return set(yPos, Target.Y); }
public ConstrainBuilder width(Constrain width) { return set(width, Target.WIDTH); }
public ConstrainBuilder height(Constrain height) { return set(height, Target.HEIGHT); }
public ConstrainBuilder xPos(float xPos) { return set(new PixelConstrain(xPos), Target.X); }
public ConstrainBuilder yPos(float yPos) { return set(new PixelConstrain(yPos), Target.Y); }
public ConstrainBuilder width(float width) { return set(new PixelConstrain(width), Target.WIDTH); }
public ConstrainBuilder height(float height) { return set(new PixelConstrain(height), Target.HEIGHT); }
public ConstrainBuilder xPosR(float xPos) { return set(new RelativeConstrain(xPos), Target.X); }
public ConstrainBuilder yPosR(float yPos) { return set(new RelativeConstrain(yPos), Target.Y); }
public ConstrainBuilder widthR(float width) { return set(new RelativeConstrain(width), Target.WIDTH); }
public ConstrainBuilder heightR(float height) { return set(new RelativeConstrain(height), Target.HEIGHT); }
public ConstrainBuilder parent(Target target) { return set(new ParentConstrain(), target); }
public ConstrainBuilder invParent(Target target) { return set(new ParentConstrain().invert(), target); }
public ConstrainBuilder parent(float padding, Target target) { return set(new ParentConstrain(padding), target); }
public ConstrainBuilder invParent(float padding, Target target) { return set(new ParentConstrain(padding).invert(), target); }
public ConstrainBuilder pixel(float pixels, Target target) { return set(new PixelConstrain(pixels), target); }
public ConstrainBuilder invPixel(float pixels, Target target) { return set(new PixelConstrain(pixels).setInverted(), target); }
public ConstrainBuilder center(Target target) { return set(new CenterConstrain(), target); }
public ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return set(new DynamicConstrain(provider), target); }
public Constrains build()
{
return new Constrains(constrains);
}
}
}

View File

@ -1,80 +1,80 @@
package speiger.src.coreengine.rendering.gui.renderer.buffer;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.models.DrawCall;
import speiger.src.coreengine.rendering.tesselation.Tesselator;
import speiger.src.coreengine.rendering.tesselation.VertexList;
import speiger.src.coreengine.utils.collections.iterators.IndexIterator;
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
public class RenderBuffer implements Consumer<GuiComponent>, Iterable<DrawCall>
{
List<DrawCall> drawCalls = new ObjectArrayList<DrawCall>();
Tesselator tesselator;
public RenderBuffer(Tesselator tesselator)
{
this.tesselator = tesselator;
}
@Override
public void accept(GuiComponent t)
{
clear();
}
public <T extends DrawCall> T get(int index, Class<T> clz)
{
return (T)drawCalls.get(index);
}
public void addDrawCall(DrawCall call)
{
drawCalls.add(call);
}
public void clear()
{
drawCalls.clear();
}
public Tesselator start(int shape, VertexList format)
{
return tesselator.begin(shape, format);
}
public void finishShape(int texture, Tesselator tesselator)
{
if(!tesselator.isDrawing())
{
throw new IllegalStateException("Tesselator wasnt filled");
}
tesselator.finishData();
if(tesselator.getVertexCount() <= 0)
{
return;
}
drawCalls.add(tesselator.getDrawCall(texture));
}
public void finishShape(int texture)
{
finishShape(texture, tesselator);
}
@Override
public Iterator<DrawCall> iterator()
{
return drawCalls.iterator();
}
public Iterable<DrawCall> selectionIterator(int...indexes)
{
return IterableWrapper.wrap(new IndexIterator<>(drawCalls, indexes));
}
}
package speiger.src.coreengine.rendering.gui.renderer.buffer;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.models.DrawCall;
import speiger.src.coreengine.rendering.tesselation.Tesselator;
import speiger.src.coreengine.rendering.tesselation.VertexList;
import speiger.src.coreengine.utils.collections.iterators.IndexIterator;
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
public class RenderBuffer implements Consumer<GuiComponent>, Iterable<DrawCall>
{
List<DrawCall> drawCalls = new ObjectArrayList<>();
Tesselator tesselator;
public RenderBuffer(Tesselator tesselator)
{
this.tesselator = tesselator;
}
@Override
public void accept(GuiComponent t)
{
clear();
}
public <T extends DrawCall> T get(int index, Class<T> clz)
{
return (T)drawCalls.get(index);
}
public void addDrawCall(DrawCall call)
{
drawCalls.add(call);
}
public void clear()
{
drawCalls.clear();
}
public Tesselator start(int shape, VertexList format)
{
return tesselator.begin(shape, format);
}
public void finishShape(int texture, Tesselator tesselator)
{
if(!tesselator.isDrawing())
{
throw new IllegalStateException("Tesselator wasnt filled");
}
tesselator.finishData();
if(tesselator.getVertexCount() <= 0)
{
return;
}
drawCalls.add(tesselator.getDrawCall(texture));
}
public void finishShape(int texture)
{
finishShape(texture, tesselator);
}
@Override
public Iterator<DrawCall> iterator()
{
return drawCalls.iterator();
}
public Iterable<DrawCall> selectionIterator(int...indexes)
{
return IterableWrapper.wrap(new IndexIterator<>(drawCalls, indexes));
}
}

View File

@ -1,142 +1,142 @@
package speiger.src.coreengine.rendering.gui.renderer.lexer;
import java.util.List;
import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.utils.ObjectIterators;
import speiger.src.coreengine.rendering.gui.renderer.IFontRenderer.CharInstance;
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
public class Line
{
float totalWidth;
float width;
int totalLetters = 0;
String result = null;
List<Word> words = new ObjectArrayList<Word>();
public Line(float totalWidth)
{
this.totalWidth = totalWidth;
}
public boolean attemptAddingWord(Word word)
{
if(word.getWidth() + width > totalWidth)
{
return false;
}
width += word.getWidth();
words.add(word);
totalLetters += word.size();
return true;
}
public void addWord(Word word)
{
width += word.getWidth();
words.add(word);
totalLetters += word.size();
}
protected void finishLine()
{
StringBuilder builder = new StringBuilder();
for(Word word : words)
{
builder.append(word.getLetters());
}
result = builder.toString();
}
public int getIndex(float width, boolean total)
{
if(width <= 0F) return (total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0;
if(width >= this.width) return ((total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0) + totalLetters;
int letters = (total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0;
for(int i = 0,m=words.size();i<m;i++)
{
Word word = words.get(i);
if(word.getWidth() > width)
{
return letters + word.getIndex(width);
}
width -= word.getWidth();
letters += word.size();
}
return letters;
}
public String getText()
{
return result;
}
public boolean isEmpty()
{
return words.isEmpty();
}
public int size()
{
return totalLetters;
}
public int getStart()
{
return words.isEmpty() ? 0 : words.get(0).getStartIndex();
}
public int getEnd()
{
return words.isEmpty() ? 0 : words.get(words.size() - 1).getEndIndex();
}
public Word getWord(int letterIndex)
{
for(int i = 0;i<words.size();i++)
{
Word word = words.get(i);
if(word.size() >= letterIndex)
{
return word;
}
letterIndex -= word.size();
}
return null;
}
public float getWidth()
{
return width;
}
public float getWidth(int index)
{
if(index <= 0) return 0F;
else if(index >= totalLetters) return width;
float width = 0F;
for(int i = 0,m=words.size();i<m;i++)
{
Word word = words.get(i);
if(word.size() > index)
{
return width + word.getWidth(index);
}
width += word.getWidth();
index -= word.size();
}
return 0;
}
public Iterable<CharInstance> letterIterator()
{
ObjectIterator<CharInstance>[] arrays = new ObjectIterator[words.size()];
for(int i = 0,m=words.size();i<m;i++)
{
arrays[i] = words.get(i).objectInstanceIterator();
}
return IterableWrapper.wrap(ObjectIterators.concat(arrays));
}
}
package speiger.src.coreengine.rendering.gui.renderer.lexer;
import java.util.List;
import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.utils.ObjectIterators;
import speiger.src.coreengine.rendering.gui.renderer.IFontRenderer.CharInstance;
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
public class Line
{
float totalWidth;
float width;
int totalLetters = 0;
String result = null;
List<Word> words = new ObjectArrayList<>();
public Line(float totalWidth)
{
this.totalWidth = totalWidth;
}
public boolean attemptAddingWord(Word word)
{
if(word.getWidth() + width > totalWidth)
{
return false;
}
width += word.getWidth();
words.add(word);
totalLetters += word.size();
return true;
}
public void addWord(Word word)
{
width += word.getWidth();
words.add(word);
totalLetters += word.size();
}
protected void finishLine()
{
StringBuilder builder = new StringBuilder();
for(Word word : words)
{
builder.append(word.getLetters());
}
result = builder.toString();
}
public int getIndex(float width, boolean total)
{
if(width <= 0F) return (total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0;
if(width >= this.width) return ((total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0) + totalLetters;
int letters = (total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0;
for(int i = 0,m=words.size();i<m;i++)
{
Word word = words.get(i);
if(word.getWidth() > width)
{
return letters + word.getIndex(width);
}
width -= word.getWidth();
letters += word.size();
}
return letters;
}
public String getText()
{
return result;
}
public boolean isEmpty()
{
return words.isEmpty();
}
public int size()
{
return totalLetters;
}
public int getStart()
{
return words.isEmpty() ? 0 : words.get(0).getStartIndex();
}
public int getEnd()
{
return words.isEmpty() ? 0 : words.get(words.size() - 1).getEndIndex();
}
public Word getWord(int letterIndex)
{
for(int i = 0;i<words.size();i++)
{
Word word = words.get(i);
if(word.size() >= letterIndex)
{
return word;
}
letterIndex -= word.size();
}
return null;
}
public float getWidth()
{
return width;
}
public float getWidth(int index)
{
if(index <= 0) return 0F;
else if(index >= totalLetters) return width;
float width = 0F;
for(int i = 0,m=words.size();i<m;i++)
{
Word word = words.get(i);
if(word.size() > index)
{
return width + word.getWidth(index);
}
width += word.getWidth();
index -= word.size();
}
return 0;
}
public Iterable<CharInstance> letterIterator()
{
ObjectIterator<CharInstance>[] arrays = new ObjectIterator[words.size()];
for(int i = 0,m=words.size();i<m;i++)
{
arrays[i] = words.get(i).objectInstanceIterator();
}
return IterableWrapper.wrap(ObjectIterators.concat(arrays));
}
}

View File

@ -1,158 +1,158 @@
package speiger.src.coreengine.rendering.gui.renderer.lexer;
import java.util.List;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.vector.ints.Vec2i;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
public class TextMetadata
{
TextComponent owner;
List<Line> lines = new ObjectArrayList<Line>();
float startX;
float startY;
float maxHeight;
float maxWidth = 0F;
float scale;
public TextMetadata(TextComponent owner)
{
this.owner = owner;
}
public void clear()
{
scale = owner.getTextScale();
lines.clear();
maxWidth = 0F;
maxHeight = 0F;
startX = 0F;
startY = 0F;
}
public void addLine(Line line)
{
lines.add(line);
maxWidth = Math.max(maxWidth, line.getWidth());
maxHeight = lines.size() * owner.getFont().height() * scale;
}
public void setStart(float x, float y)
{
startX = x;
startY = y;
}
public float getStartX()
{
return startX;
}
public float getStartY()
{
return startY;
}
public float getMaxHeight()
{
return maxHeight;
}
public float getMaxWidth()
{
return maxWidth;
}
public float getWidth(int letterIndex)
{
return lines.isEmpty() ? 0F : lines.get(0).getWidth(letterIndex);
}
public float getWidth(int posX, int posY)
{
return lines.size() > posY ? lines.get(posY).getWidth(posX) : 0F;
}
public float getLineWidth(int line)
{
return lines.size() > line ? lines.get(line).getWidth() : 0F;
}
public Word getWord(int letterIndex)
{
return lines.isEmpty() ? null : lines.get(0).getWord(letterIndex);
}
public Line getLine(int line)
{
return lines.size() > line ? lines.get(line) : null;
}
public int moveUp(Vec2i pos)
{
if(pos.getY() + 1 < lines.size())
{
float width = lines.get(pos.getY()).getWidth(pos.getX());
return lines.get(pos.getY() + 1).getIndex(width, true);
}
return lines.isEmpty() ? 0 : lines.get(lines.size() - 1).getEnd();
}
public int moveDown(Vec2i pos)
{
if(pos.getY() > 0 && pos.getY() - 1 < lines.size())
{
float width = lines.get(pos.getY()).getWidth(pos.getX());
return lines.get(pos.getY() - 1).getIndex(width, true);
}
return lines.isEmpty() ? 0 : lines.get(0).getStart();
}
public int getIndex(float width)
{
return lines.size() > 0 ? lines.get(0).getIndex(width, false) : 0;
}
public int getIndex(float width, float height)
{
return lines.isEmpty() ? 0 : lines.get(MathUtils.clamp(0, lines.size() - 1, (int)(height / (owner.getFont().height() * scale)))).getIndex(width, true);
}
public void getIndex(float width, float height, Vec2i result)
{
if(lines.isEmpty())
{
result.negate();
return;
}
int index = MathUtils.clamp(0, lines.size() - 1, (int)(height / (owner.getFont().height() * scale)));
result.set(lines.get(index).getIndex(width, false), index);
}
public void convert(int index, Vec2i result)
{
result.set(Vec2i.ZERO);
for(int i = 0,m=lines.size();i<m;i++)
{
Line line = lines.get(i);
if(line.size() >= index)
{
result.add(index, i);
return;
}
index -= line.size();
}
}
public int convert(Vec2i input)
{
int index = input.getX();
for(int i = 0,m=input.getY();i<m;i++)
{
index += lines.get(i).size();
}
return index;
}
}
package speiger.src.coreengine.rendering.gui.renderer.lexer;
import java.util.List;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.vector.ints.Vec2i;
import speiger.src.coreengine.rendering.gui.components.TextComponent;
public class TextMetadata
{
TextComponent owner;
List<Line> lines = new ObjectArrayList<>();
float startX;
float startY;
float maxHeight;
float maxWidth = 0F;
float scale;
public TextMetadata(TextComponent owner)
{
this.owner = owner;
}
public void clear()
{
scale = owner.getTextScale();
lines.clear();
maxWidth = 0F;
maxHeight = 0F;
startX = 0F;
startY = 0F;
}
public void addLine(Line line)
{
lines.add(line);
maxWidth = Math.max(maxWidth, line.getWidth());
maxHeight = lines.size() * owner.getFont().height() * scale;
}
public void setStart(float x, float y)
{
startX = x;
startY = y;
}
public float getStartX()
{
return startX;
}
public float getStartY()
{
return startY;
}
public float getMaxHeight()
{
return maxHeight;
}
public float getMaxWidth()
{
return maxWidth;
}
public float getWidth(int letterIndex)
{
return lines.isEmpty() ? 0F : lines.get(0).getWidth(letterIndex);
}
public float getWidth(int posX, int posY)
{
return lines.size() > posY ? lines.get(posY).getWidth(posX) : 0F;
}
public float getLineWidth(int line)
{
return lines.size() > line ? lines.get(line).getWidth() : 0F;
}
public Word getWord(int letterIndex)
{
return lines.isEmpty() ? null : lines.get(0).getWord(letterIndex);
}
public Line getLine(int line)
{
return lines.size() > line ? lines.get(line) : null;
}
public int moveUp(Vec2i pos)
{
if(pos.getY() + 1 < lines.size())
{
float width = lines.get(pos.getY()).getWidth(pos.getX());
return lines.get(pos.getY() + 1).getIndex(width, true);
}
return lines.isEmpty() ? 0 : lines.get(lines.size() - 1).getEnd();
}
public int moveDown(Vec2i pos)
{
if(pos.getY() > 0 && pos.getY() - 1 < lines.size())
{
float width = lines.get(pos.getY()).getWidth(pos.getX());
return lines.get(pos.getY() - 1).getIndex(width, true);
}
return lines.isEmpty() ? 0 : lines.get(0).getStart();
}
public int getIndex(float width)
{
return lines.size() > 0 ? lines.get(0).getIndex(width, false) : 0;
}
public int getIndex(float width, float height)
{
return lines.isEmpty() ? 0 : lines.get(MathUtils.clamp(0, lines.size() - 1, (int)(height / (owner.getFont().height() * scale)))).getIndex(width, true);
}
public void getIndex(float width, float height, Vec2i result)
{
if(lines.isEmpty())
{
result.negate();
return;
}
int index = MathUtils.clamp(0, lines.size() - 1, (int)(height / (owner.getFont().height() * scale)));
result.set(lines.get(index).getIndex(width, false), index);
}
public void convert(int index, Vec2i result)
{
result.set(Vec2i.ZERO);
for(int i = 0,m=lines.size();i<m;i++)
{
Line line = lines.get(i);
if(line.size() >= index)
{
result.add(index, i);
return;
}
index -= line.size();
}
}
public int convert(Vec2i input)
{
int index = input.getX();
for(int i = 0,m=input.getY();i<m;i++)
{
index += lines.get(i).size();
}
return index;
}
}

View File

@ -1,23 +1,23 @@
package speiger.src.coreengine.rendering.shader;
import java.util.List;
import java.util.function.Consumer;
public class ShaderEntry<T> implements Consumer<T>
{
List<T> shaders;
int index;
public ShaderEntry(List<T> shaders, int index)
{
this.shaders = shaders;
this.index = index;
}
@Override
public void accept(T t)
{
shaders.set(index, t);
}
}
package speiger.src.coreengine.rendering.shader;
import java.util.List;
import java.util.function.Consumer;
public class ShaderEntry<T> implements Consumer<T>
{
List<T> shaders;
int index;
public ShaderEntry(List<T> shaders, int index)
{
this.shaders = shaders;
this.index = index;
}
@Override
public void accept(T t)
{
shaders.set(index, t);
}
}

View File

@ -1,276 +1,276 @@
package speiger.src.coreengine.rendering.tesselation;
import java.nio.FloatBuffer;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.math.vector.floats.Vec3f;
import speiger.src.coreengine.rendering.models.DrawCall;
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
public class Tesselator implements IVertexBuilder
{
boolean drawing = false;
int drawType = 0;
VertexList currentList;
VertexElement currentElement;
int currentIndex = 0;
Vec3f offset = Vec3f.mutable();
Vec2f effects = Vec2f.mutable(1F);
FloatBuffer buffer;
int vertexes = 0;
public Tesselator(int capacity)
{
buffer = FloatBuffer.allocate(capacity);
}
public Tesselator(FloatBuffer buffer)
{
this.buffer = buffer;
}
public Tesselator begin(int glType, VertexList list)
{
if(drawing)
{
throw new RuntimeException("Already Drawing");
}
drawType = glType;
drawing = true;
currentList = list;
currentElement = list.getElement(0);
currentIndex = 0;
buffer.clear();
vertexes = 0;
return this;
}
public Tesselator changeGLType(int glType)
{
if(!drawing)
{
throw new RuntimeException("Can not change type");
}
drawType = glType;
return this;
}
public Tesselator resetVertexes()
{
vertexes = 0;
return this;
}
public Tesselator setBrightness(float value)
{
effects.setX(value);
return this;
}
public Tesselator setVisibilty(float value)
{
effects.setY(value);
return this;
}
public float getBrightness()
{
return effects.getX();
}
public float getVisibility()
{
return effects.getY();
}
public Tesselator resetEffects()
{
effects.set(Vec2f.ONE);
return this;
}
public Tesselator offset(float x, float y, float z)
{
offset.add(x, y, z);
return this;
}
public Tesselator setOffset(float x, float y, float z)
{
offset.set(x, y, z);
return this;
}
@Override
public Tesselator pos(float x, float y)
{
validateElement(ElementUsage.POS, 2);
buffer.put(x + offset.getX());
buffer.put(y + offset.getY());
nextElement();
return this;
}
@Override
public Tesselator pos(float x, float y, float z)
{
validateElement(ElementUsage.POS, 3);
buffer.put(x + offset.getX());
buffer.put(y + offset.getY());
buffer.put(z + offset.getZ());
nextElement();
return this;
}
@Override
public Tesselator color3f(float r, float g, float b)
{
validateElement(ElementUsage.COLOR, 3);
buffer.put(r * effects.getX());
buffer.put(g * effects.getX());
buffer.put(b * effects.getX());
nextElement();
return this;
}
@Override
public Tesselator color4f(float r, float g, float b, float a)
{
validateElement(ElementUsage.COLOR, 4);
buffer.put(r * effects.getX());
buffer.put(g * effects.getX());
buffer.put(b * effects.getX());
buffer.put(a * effects.getY());
nextElement();
return this;
}
@Override
public Tesselator tex(float u, float v)
{
validateElement(ElementUsage.UV, 2);
buffer.put(u);
buffer.put(v);
nextElement();
return this;
}
@Override
public Tesselator normal(float x, float y, float z)
{
validateElement(ElementUsage.NORMAL, 3);
buffer.put(x);
buffer.put(y);
buffer.put(z);
nextElement();
return this;
}
@Override
public Tesselator custom(float x)
{
validateElement(ElementUsage.CUSTOM, 1);
buffer.put(x);
nextElement();
return this;
}
@Override
public Tesselator custom(float x, float y)
{
validateElement(ElementUsage.CUSTOM, 2);
buffer.put(x);
buffer.put(y);
nextElement();
return this;
}
@Override
public Tesselator custom(float x, float y, float z)
{
validateElement(ElementUsage.CUSTOM, 3);
buffer.put(x);
buffer.put(y);
buffer.put(z);
nextElement();
return this;
}
@Override
public Tesselator custom(float x, float y, float z, float w)
{
validateElement(ElementUsage.CUSTOM, 4);
buffer.put(x);
buffer.put(y);
buffer.put(z);
buffer.put(w);
nextElement();
return this;
}
@Override
public Tesselator endVertex()
{
vertexes++;
return this;
}
public Tesselator finishData()
{
drawing = false;
buffer.flip();
return this;
}
public float[] getData()
{
float[] data = new float[currentList.getOffsets() * vertexes];
buffer.get(data);
return data;
}
public DrawCall getDrawCall(int texture)
{
float[] data = new float[currentList.getOffsets() * vertexes];
buffer.get(data);
return new DrawCall(drawType, texture, data, vertexes);
}
public boolean isDrawing()
{
return drawing;
}
public boolean hasTexture()
{
return currentList.hasType(ElementUsage.UV);
}
public int getGLDrawType()
{
return drawType;
}
public void validateElement(ElementUsage usage, int componentSize)
{
if(currentElement.getUsage() == usage && currentElement.getSize() == componentSize && drawing)
{
return;
}
throw new RuntimeException("Invalid Argument, Drawing: "+drawing+", Element: "+usage+", Expected: "+currentElement.getUsage()+", Size: "+componentSize+", Expected Size: "+currentElement.getSize());
}
protected void nextElement()
{
currentIndex = (currentIndex + 1) % currentList.getElementCount();
currentElement = currentList.getElement(currentIndex);
}
public int getVertexCount()
{
return vertexes;
}
}
package speiger.src.coreengine.rendering.tesselation;
import java.nio.FloatBuffer;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.math.vector.floats.Vec3f;
import speiger.src.coreengine.rendering.models.DrawCall;
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
public class Tesselator implements IVertexBuilder
{
boolean drawing = false;
int drawType = 0;
VertexList currentList;
VertexElement currentElement;
int currentIndex = 0;
Vec3f offset = Vec3f.mutable();
Vec2f effects = Vec2f.mutable(1F);
FloatBuffer buffer;
int vertexes = 0;
public Tesselator(int capacity)
{
buffer = FloatBuffer.allocate(capacity);
}
public Tesselator(FloatBuffer buffer)
{
this.buffer = buffer;
}
public Tesselator begin(int glType, VertexList list)
{
if(drawing)
{
throw new RuntimeException("Already Drawing");
}
drawType = glType;
drawing = true;
currentList = list;
currentElement = list.get(0);
currentIndex = 0;
buffer.clear();
vertexes = 0;
return this;
}
public Tesselator changeGLType(int glType)
{
if(!drawing)
{
throw new RuntimeException("Can not change type");
}
drawType = glType;
return this;
}
public Tesselator resetVertexes()
{
vertexes = 0;
return this;
}
public Tesselator setBrightness(float value)
{
effects.setX(value);
return this;
}
public Tesselator setVisibilty(float value)
{
effects.setY(value);
return this;
}
public float getBrightness()
{
return effects.getX();
}
public float getVisibility()
{
return effects.getY();
}
public Tesselator resetEffects()
{
effects.set(Vec2f.ONE);
return this;
}
public Tesselator offset(float x, float y, float z)
{
offset.add(x, y, z);
return this;
}
public Tesselator setOffset(float x, float y, float z)
{
offset.set(x, y, z);
return this;
}
@Override
public Tesselator pos(float x, float y)
{
validateElement(ElementUsage.POS, 2);
buffer.put(x + offset.getX());
buffer.put(y + offset.getY());
nextElement();
return this;
}
@Override
public Tesselator pos(float x, float y, float z)
{
validateElement(ElementUsage.POS, 3);
buffer.put(x + offset.getX());
buffer.put(y + offset.getY());
buffer.put(z + offset.getZ());
nextElement();
return this;
}
@Override
public Tesselator color3f(float r, float g, float b)
{
validateElement(ElementUsage.COLOR, 3);
buffer.put(r * effects.getX());
buffer.put(g * effects.getX());
buffer.put(b * effects.getX());
nextElement();
return this;
}
@Override
public Tesselator color4f(float r, float g, float b, float a)
{
validateElement(ElementUsage.COLOR, 4);
buffer.put(r * effects.getX());
buffer.put(g * effects.getX());
buffer.put(b * effects.getX());
buffer.put(a * effects.getY());
nextElement();
return this;
}
@Override
public Tesselator tex(float u, float v)
{
validateElement(ElementUsage.UV, 2);
buffer.put(u);
buffer.put(v);
nextElement();
return this;
}
@Override
public Tesselator normal(float x, float y, float z)
{
validateElement(ElementUsage.NORMAL, 3);
buffer.put(x);
buffer.put(y);
buffer.put(z);
nextElement();
return this;
}
@Override
public Tesselator custom(float x)
{
validateElement(ElementUsage.CUSTOM, 1);
buffer.put(x);
nextElement();
return this;
}
@Override
public Tesselator custom(float x, float y)
{
validateElement(ElementUsage.CUSTOM, 2);
buffer.put(x);
buffer.put(y);
nextElement();
return this;
}
@Override
public Tesselator custom(float x, float y, float z)
{
validateElement(ElementUsage.CUSTOM, 3);
buffer.put(x);
buffer.put(y);
buffer.put(z);
nextElement();
return this;
}
@Override
public Tesselator custom(float x, float y, float z, float w)
{
validateElement(ElementUsage.CUSTOM, 4);
buffer.put(x);
buffer.put(y);
buffer.put(z);
buffer.put(w);
nextElement();
return this;
}
@Override
public Tesselator endVertex()
{
vertexes++;
return this;
}
public Tesselator finishData()
{
drawing = false;
buffer.flip();
return this;
}
public float[] getData()
{
float[] data = new float[currentList.getOffsets() * vertexes];
buffer.get(data);
return data;
}
public DrawCall getDrawCall(int texture)
{
float[] data = new float[currentList.getOffsets() * vertexes];
buffer.get(data);
return new DrawCall(drawType, texture, data, vertexes);
}
public boolean isDrawing()
{
return drawing;
}
public boolean hasTexture()
{
return currentList.hasType(ElementUsage.UV);
}
public int getGLDrawType()
{
return drawType;
}
public void validateElement(ElementUsage usage, int componentSize)
{
if(currentElement.getUsage() == usage && currentElement.getSize() == componentSize && drawing)
{
return;
}
throw new RuntimeException("Invalid Argument, Drawing: "+drawing+", Element: "+usage+", Expected: "+currentElement.getUsage()+", Size: "+componentSize+", Expected Size: "+currentElement.getSize());
}
protected void nextElement()
{
currentIndex = (currentIndex + 1) % currentList.size();
currentElement = currentList.get(currentIndex);
}
public int getVertexCount()
{
return vertexes;
}
}

View File

@ -1,71 +1,69 @@
package speiger.src.coreengine.rendering.tesselation;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import speiger.src.collections.ints.lists.IntArrayList;
import speiger.src.collections.ints.lists.IntList;
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
import speiger.src.coreengine.utils.collections.iterators.ReadOnlyIterator;
public class VertexList implements Iterable<VertexElement>
{
List<VertexElement> elements = new ArrayList<VertexElement>();
Set<ElementUsage> types = EnumSet.noneOf(ElementUsage.class);
IntList offsets = new IntArrayList();
int totalOffset;
public VertexList()
{
}
public VertexList(VertexList vertexList)
{
elements.addAll(vertexList.elements);
offsets.addAll(vertexList.offsets);
totalOffset = vertexList.totalOffset;
}
public void addElement(VertexElement element)
{
elements.add(element);
offsets.add(totalOffset);
totalOffset += element.getSize();
types.add(element.getUsage());
}
public int getOffsets()
{
return totalOffset;
}
public int getElementCount()
{
return elements.size();
}
public VertexElement getElement(int index)
{
return elements.get(index);
}
public int getOffset(int index)
{
return offsets.getInt(index);
}
@Override
public Iterator<VertexElement> iterator()
{
return new ReadOnlyIterator<VertexElement>(elements.iterator());
}
public boolean hasType(ElementUsage type)
{
return types.contains(type);
}
}
package speiger.src.coreengine.rendering.tesselation;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import speiger.src.collections.ints.lists.IntArrayList;
import speiger.src.collections.ints.lists.IntList;
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
import speiger.src.coreengine.utils.collections.iterators.ReadOnlyIterator;
public class VertexList implements Iterable<VertexElement>
{
List<VertexElement> elements = new ArrayList<VertexElement>();
Set<ElementUsage> types = EnumSet.noneOf(ElementUsage.class);
IntList offsets = new IntArrayList();
int totalOffset;
public VertexList() {}
public VertexList(VertexList vertexList)
{
elements.addAll(vertexList.elements);
offsets.addAll(vertexList.offsets);
totalOffset = vertexList.totalOffset;
}
public VertexList add(VertexElement element)
{
elements.add(element);
offsets.add(totalOffset);
totalOffset += element.getSize();
types.add(element.getUsage());
return this;
}
public int getOffsets()
{
return totalOffset;
}
public int size()
{
return elements.size();
}
public VertexElement get(int index)
{
return elements.get(index);
}
public int getOffset(int index)
{
return offsets.getInt(index);
}
@Override
public Iterator<VertexElement> iterator()
{
return new ReadOnlyIterator<>(elements.iterator());
}
public boolean hasType(ElementUsage type)
{
return types.contains(type);
}
}

View File

@ -1,47 +1,23 @@
package speiger.src.coreengine.rendering.tesselation;
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
public class VertexType
{
public static final VertexElement POSITION_2F = new VertexElement(2, ElementUsage.POS);
public static final VertexElement POSITION_3F = new VertexElement(3, ElementUsage.POS);
public static final VertexElement TEXTURE_2F = new VertexElement(2, ElementUsage.UV);
public static final VertexElement COLOR_3F = new VertexElement(3, ElementUsage.COLOR);
public static final VertexElement COLOR_4F = new VertexElement(4, ElementUsage.COLOR);
public static final VertexElement NORMAL_3F = new VertexElement(3, ElementUsage.NORMAL);
public static final VertexElement CUSTOM_4F = new VertexElement(4, ElementUsage.CUSTOM);
public static final VertexList POS_COLOR_3F = new VertexList();
public static final VertexList POS_COLOR_4F = new VertexList();
public static final VertexList POS_COLOR_2F = new VertexList();
public static final VertexList POS_TEX = new VertexList();
public static final VertexList TERRAIN = new VertexList();
public static final VertexList UI = new VertexList();
public static final VertexList IN_WORLD_UI = new VertexList();
static
{
UI.addElement(POSITION_3F);
UI.addElement(TEXTURE_2F);
UI.addElement(COLOR_4F);
IN_WORLD_UI.addElement(POSITION_3F);
IN_WORLD_UI.addElement(TEXTURE_2F);
IN_WORLD_UI.addElement(COLOR_4F);
IN_WORLD_UI.addElement(CUSTOM_4F);
TERRAIN.addElement(POSITION_3F);
TERRAIN.addElement(COLOR_3F);
TERRAIN.addElement(NORMAL_3F);
POS_COLOR_2F.addElement(POSITION_2F);
POS_COLOR_2F.addElement(COLOR_4F);
POS_COLOR_3F.addElement(POSITION_3F);
POS_COLOR_3F.addElement(COLOR_3F);
POS_COLOR_4F.addElement(POSITION_3F);
POS_COLOR_4F.addElement(COLOR_4F);
POS_TEX.addElement(POSITION_3F);
POS_TEX.addElement(TEXTURE_2F);
}
}
package speiger.src.coreengine.rendering.tesselation;
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
public class VertexType
{
public static final VertexElement POSITION_2F = new VertexElement(2, ElementUsage.POS);
public static final VertexElement POSITION_3F = new VertexElement(3, ElementUsage.POS);
public static final VertexElement TEXTURE_2F = new VertexElement(2, ElementUsage.UV);
public static final VertexElement COLOR_3F = new VertexElement(3, ElementUsage.COLOR);
public static final VertexElement COLOR_4F = new VertexElement(4, ElementUsage.COLOR);
public static final VertexElement NORMAL_3F = new VertexElement(3, ElementUsage.NORMAL);
public static final VertexElement CUSTOM_4F = new VertexElement(4, ElementUsage.CUSTOM);
public static final VertexList POS_COLOR_2F = new VertexList().add(POSITION_2F).add(COLOR_4F);
public static final VertexList POS_COLOR_3F = new VertexList().add(POSITION_3F).add(COLOR_3F);
public static final VertexList POS_COLOR_4F = new VertexList().add(POSITION_3F).add(COLOR_4F);
public static final VertexList POS_TEX = new VertexList().add(POSITION_3F).add(TEXTURE_2F);
public static final VertexList TERRAIN = new VertexList().add(POSITION_3F).add(COLOR_3F).add(NORMAL_3F);
public static final VertexList UI = new VertexList().add(POSITION_3F).add(TEXTURE_2F).add(COLOR_4F);
public static final VertexList IN_WORLD_UI = new VertexList().add(POSITION_3F).add(TEXTURE_2F).add(COLOR_4F).add(CUSTOM_4F);
}

View File

@ -1,131 +1,139 @@
package speiger.src.coreengine.rendering.utils;
import java.nio.IntBuffer;
import java.util.List;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL44;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.utils.states.BlendState;
import speiger.src.coreengine.rendering.utils.states.CullState;
import speiger.src.coreengine.rendering.utils.states.GLProvoking;
import speiger.src.coreengine.rendering.utils.states.GLState;
import speiger.src.coreengine.rendering.utils.states.GLWireFrame;
import speiger.src.coreengine.rendering.utils.states.IGLState;
import speiger.src.coreengine.rendering.utils.states.LineSize;
import speiger.src.coreengine.rendering.utils.states.PointSize;
import speiger.src.coreengine.utils.counters.averager.Counter;
public class GLUtils
{
static final List<IGLState> ALL_STATES = new ObjectArrayList<>();
public static final GLState MULTI_SAMPLING = addState(new GLState(GL13.GL_MULTISAMPLE, false));
public static final GLState WIRE_FRAME = addState(new GLWireFrame());
public static final GLState PROVOKING_VERTEX = addState(new GLProvoking());
public static final GLState DEBTH_TEST = addState(new GLState(GL11.GL_DEPTH_TEST, false));
public static final CullState CULL_FACE = addState(new CullState(GL11.GL_BACK));
public static final BlendState BLEND = addState(new BlendState());
public static final GLState CLIP_PLANE0 = addState(new GLState(GL11.GL_CLIP_PLANE0, false));
public static final PointSize POINT_SIZE = addState(new PointSize());
public static final LineSize LINE_SIZE = addState(new LineSize());
public static final ScissorsManager TESTER = new ScissorsManager(100);
public static final Counter[] COUNTERS = Counter.createCounters(4);
public static final ViewPortStack VIEW_PORT = new ViewPortStack();
public static <T extends IGLState> T addState(T state)
{
ALL_STATES.add(state);
return state;
}
public static void onFrameEnded()
{
for(int i = 0,m=COUNTERS.length;i<m;i++)
{
COUNTERS[i].onFinished();
}
for(int i = 0;i<ALL_STATES.size();i++)
{
ALL_STATES.get(i).cleanup();
}
}
public static void drawArrays(int mode, int count)
{
drawArrays(mode, 0, count);
}
public static void drawArrays(int mode, int first, int count)
{
addVerties(mode, count);
GL11.glDrawArrays(mode, first, count);
}
public static void drawElements(int mode, int count, int type, long indices)
{
addVerties(mode, count);
GL11.glDrawElements(mode, count, type, indices);
}
public static void drawElements(int mode, IntBuffer buffer)
{
addVerties(mode, buffer.remaining());
GL11.glDrawElements(mode, buffer);
}
public static void drawArraysInstanced(int mode, int first, int count, int instanced)
{
addVerties(mode, count * instanced);
GL31.glDrawArraysInstanced(mode, first, count, instanced);
}
public static void drawElementsInstanced(int mode, int count, int type, long indices, int instanced)
{
addVerties(mode, count * instanced);
GL31.glDrawElementsInstanced(mode, count, type, indices, instanced);
}
public static void drawElementsIndirect(int mode, int type, long pointer, int drawCount, int stride)
{
addVerties(mode, drawAmount(pointer, drawCount));
GL44.glMultiDrawElementsIndirect(mode, type, pointer, drawCount, stride);
}
static int drawAmount(long pointer, int amount)
{
int total = 0;
return total;
}
static void addVerties(int mode, int count)
{
COUNTERS[0].add(count);
switch(mode)
{
case GL11.GL_POINTS:
COUNTERS[1].add(count);
break;
case GL11.GL_LINES:
COUNTERS[2].add(count / 2);
break;
case GL11.GL_LINE_LOOP:
COUNTERS[2].add((count + 2) / 2);
break;
case GL11.GL_LINE_STRIP:
COUNTERS[2].add(count - 1);
break;
case GL11.GL_TRIANGLES:
COUNTERS[3].add(count / 3);
break;
case GL11.GL_TRIANGLE_STRIP:
COUNTERS[3].add(count - 2);
break;
case GL11.GL_TRIANGLE_FAN:
COUNTERS[3].add(count - 2);
break;
}
}
}
package speiger.src.coreengine.rendering.utils;
import java.nio.IntBuffer;
import java.util.List;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL44;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.utils.states.BlendState;
import speiger.src.coreengine.rendering.utils.states.CullState;
import speiger.src.coreengine.rendering.utils.states.GLProvoking;
import speiger.src.coreengine.rendering.utils.states.GLState;
import speiger.src.coreengine.rendering.utils.states.GLWireFrame;
import speiger.src.coreengine.rendering.utils.states.IGLState;
import speiger.src.coreengine.rendering.utils.states.LineSize;
import speiger.src.coreengine.rendering.utils.states.PointSize;
import speiger.src.coreengine.utils.counters.averager.Counter;
public class GLUtils
{
static final List<IGLState> ALL_STATES = new ObjectArrayList<>();
public static final GLState MULTI_SAMPLING = addState(new GLState(GL13.GL_MULTISAMPLE, false));
public static final GLState WIRE_FRAME = addState(new GLWireFrame());
public static final GLState PROVOKING_VERTEX = addState(new GLProvoking());
public static final GLState DEBTH_TEST = addState(new GLState(GL11.GL_DEPTH_TEST, false));
public static final CullState CULL_FACE = addState(new CullState(GL11.GL_BACK));
public static final BlendState BLEND = addState(new BlendState());
public static final GLState CLIP_PLANE0 = addState(new GLState(GL11.GL_CLIP_PLANE0, false));
public static final PointSize POINT_SIZE = addState(new PointSize());
public static final LineSize LINE_SIZE = addState(new LineSize());
public static final ScissorsManager TESTER = new ScissorsManager(100);
public static final Counter[] COUNTERS = Counter.createCounters(4);
public static final ViewPortStack VIEW_PORT = new ViewPortStack();
public static <T extends IGLState> T addState(T state)
{
ALL_STATES.add(state);
return state;
}
public static void reapplyState()
{
for(int i = 0;i<ALL_STATES.size();i++)
{
ALL_STATES.get(i).reapply();
}
}
public static void onFrameEnded()
{
for(int i = 0,m=COUNTERS.length;i<m;i++)
{
COUNTERS[i].onFinished();
}
for(int i = 0;i<ALL_STATES.size();i++)
{
ALL_STATES.get(i).cleanup();
}
}
public static void drawArrays(int mode, int count)
{
drawArrays(mode, 0, count);
}
public static void drawArrays(int mode, int first, int count)
{
addVerties(mode, count);
GL11.glDrawArrays(mode, first, count);
}
public static void drawElements(int mode, int count, int type, long indices)
{
addVerties(mode, count);
GL11.glDrawElements(mode, count, type, indices);
}
public static void drawElements(int mode, IntBuffer buffer)
{
addVerties(mode, buffer.remaining());
GL11.glDrawElements(mode, buffer);
}
public static void drawArraysInstanced(int mode, int first, int count, int instanced)
{
addVerties(mode, count * instanced);
GL31.glDrawArraysInstanced(mode, first, count, instanced);
}
public static void drawElementsInstanced(int mode, int count, int type, long indices, int instanced)
{
addVerties(mode, count * instanced);
GL31.glDrawElementsInstanced(mode, count, type, indices, instanced);
}
public static void drawElementsIndirect(int mode, int type, long pointer, int drawCount, int stride)
{
addVerties(mode, drawAmount(pointer, drawCount));
GL44.glMultiDrawElementsIndirect(mode, type, pointer, drawCount, stride);
}
static int drawAmount(long pointer, int amount)
{
int total = 0;
return total;
}
static void addVerties(int mode, int count)
{
COUNTERS[0].add(count);
switch(mode)
{
case GL11.GL_POINTS:
COUNTERS[1].add(count);
break;
case GL11.GL_LINES:
COUNTERS[2].add(count / 2);
break;
case GL11.GL_LINE_LOOP:
COUNTERS[2].add((count + 2) / 2);
break;
case GL11.GL_LINE_STRIP:
COUNTERS[2].add(count - 1);
break;
case GL11.GL_TRIANGLES:
COUNTERS[3].add(count / 3);
break;
case GL11.GL_TRIANGLE_STRIP:
COUNTERS[3].add(count - 2);
break;
case GL11.GL_TRIANGLE_FAN:
COUNTERS[3].add(count - 2);
break;
}
}
}

View File

@ -1,248 +1,248 @@
package speiger.src.coreengine.rendering.utils;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.File;
import java.nio.ByteBuffer;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.GL11;
import org.lwjgl.system.MemoryUtil;
import speiger.src.coreengine.rendering.input.window.IWindowListener;
import speiger.src.coreengine.rendering.input.window.Window;
import speiger.src.coreengine.utils.helpers.FileUtils;
import speiger.src.coreengine.utils.io.GifWriter;
public class ScreenshotHandler implements IWindowListener
{
public static final DateTimeFormatter FILE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss");
public static final DateTimeFormatter FOLDER_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM");
static final ThreadPoolExecutor FACTORY = (ThreadPoolExecutor)Executors.newFixedThreadPool(1);
File folder;
int width;
int height;
ByteBuffer buffer;
GifRecorder recorder;
Supplier<BufferedImage> imageProvider = this::getData;
public ScreenshotHandler(File helper)
{
FACTORY.setKeepAliveTime(1, TimeUnit.SECONDS);
FACTORY.allowCoreThreadTimeOut(true);
folder = new File(helper, "Screenshots");
}
@Override
public void onWindowChanged(Window window)
{
width = window.getWidth();
height = window.getHeight();
if(buffer != null)
{
MemoryUtil.memFree(buffer);
buffer = null;
}
buffer = MemoryUtil.memAlloc(width * height * 4);
}
public void screenShot()
{
ZonedDateTime time = ZonedDateTime.now();
File subFolder = new File(folder, time.format(FOLDER_FORMAT));
FileUtils.ensureFolder(subFolder);
try
{
ImageIO.write(getScreenShot(), "png", new File(subFolder, "Screenshot_"+time.format(FILE_FORMAT)+".png"));
}
catch(Exception e)
{
e.printStackTrace();
}
}
public boolean isRecording()
{
return recorder != null && !recorder.isFinished();
}
public void toggleRecording()
{
if(isRecording())
{
stopRecording();
}
else
{
startRecording();
}
}
//Undefined time recording
public void startRecording()
{
record("Capture_"+ZonedDateTime.now().format(FILE_FORMAT)+".gif", 15, Integer.MAX_VALUE);
}
public void record(String fileName, int fps, int time)
{
if(recorder == null)
{
File subFolder = new File(folder, ZonedDateTime.now().format(FOLDER_FORMAT));
FileUtils.ensureFolder(subFolder);
recorder = new GifRecorder(new File(subFolder, fileName), fps, time);
}
}
public void stopRecording()
{
if(recorder != null)
{
recorder.finishPic();
recorder = null;
}
}
public void update()
{
if(recorder != null)
{
recorder.tick(imageProvider);
if(recorder.isFinished())
{
recorder.finishPic();
recorder = null;
}
}
}
private BufferedImage getData()
{
buffer.clear();
GL11.glReadBuffer(GL11.GL_FRONT);
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
for(int x = 0;x < width;x++)
{
for(int y = 0;y < height;y++)
{
int i = (x + (width * y)) * 4;
int r = buffer.get(i) & 0xFF;
int g = buffer.get(i + 1) & 0xFF;
int b = buffer.get(i + 2) & 0xFF;
data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b;
}
}
return image;
}
public BufferedImage getScreenShot()
{
buffer.clear();
GL11.glReadBuffer(GL11.GL_FRONT);
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
for(int x = 0;x < width;x++)
{
for(int y = 0;y < height;y++)
{
int i = (x + (width * y)) * 4;
int r = buffer.get(i) & 0xFF;
int g = buffer.get(i + 1) & 0xFF;
int b = buffer.get(i + 2) & 0xFF;
data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b;
}
}
return image;
}
public void cleanup()
{
if(buffer != null)
{
MemoryUtil.memFree(buffer);
buffer = null;
}
}
public static class GifRecorder
{
GifWriter writer;
long timeBetweenFrames;
long lastTime = -1L;
long freeTime;
int totalPics;
public GifRecorder(File file, int fps, int time)
{
int ms = 1000 / fps;
writer = GifWriter.create(file, BufferedImage.TYPE_INT_ARGB, ms);
timeBetweenFrames = ms * 1000000L;
freeTime = ms * 1000000L;
totalPics = fps * time;
}
public void tick(Supplier<BufferedImage> supply)
{
if(lastTime == -1L)
{
totalPics--;
insert(supply.get());
lastTime = System.nanoTime();
return;
}
long time = System.nanoTime();
long happend = time - lastTime;
lastTime = time;
freeTime -= happend;
if(freeTime <= 0)
{
freeTime += timeBetweenFrames;
insert(supply.get());
totalPics--;
}
}
private void insert(final BufferedImage newBuffer)
{
FACTORY.execute(new Runnable(){
BufferedImage buffer = newBuffer;
@Override
public void run()
{
if(writer != null)
{
writer.insertPicture(buffer);
}
}
});
}
public boolean isFinished()
{
return totalPics <= 0;
}
public void finishPic()
{
FACTORY.execute(new Runnable(){
@Override
public void run()
{
writer.close();
writer = null;
}
});
}
}
}
package speiger.src.coreengine.rendering.utils;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.File;
import java.nio.ByteBuffer;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.GL11;
import org.lwjgl.system.MemoryUtil;
import speiger.src.coreengine.rendering.input.window.IWindowListener;
import speiger.src.coreengine.rendering.input.window.Window;
import speiger.src.coreengine.utils.helpers.FileUtils;
import speiger.src.coreengine.utils.io.GifWriter;
public class ScreenshotHandler implements IWindowListener
{
public static final DateTimeFormatter FILE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss");
public static final DateTimeFormatter FOLDER_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM");
static final ThreadPoolExecutor FACTORY = (ThreadPoolExecutor)Executors.newFixedThreadPool(1);
File folder;
int width;
int height;
ByteBuffer buffer;
GifRecorder recorder;
Supplier<BufferedImage> imageProvider = this::getData;
public ScreenshotHandler(File helper)
{
FACTORY.setKeepAliveTime(1, TimeUnit.SECONDS);
FACTORY.allowCoreThreadTimeOut(true);
folder = new File(helper, "Screenshots");
}
@Override
public void onWindowChanged(Window window)
{
width = window.getWidth();
height = window.getHeight();
if(buffer != null)
{
MemoryUtil.memFree(buffer);
buffer = null;
}
buffer = MemoryUtil.memAlloc(width * height * 4);
}
public void screenShot()
{
ZonedDateTime time = ZonedDateTime.now();
File subFolder = new File(folder, time.format(FOLDER_FORMAT));
FileUtils.ensureFolder(subFolder);
try
{
ImageIO.write(getScreenShot(), "png", new File(subFolder, "Screenshot_"+time.format(FILE_FORMAT)+".png"));
}
catch(Exception e)
{
e.printStackTrace();
}
}
public boolean isRecording()
{
return recorder != null && !recorder.isFinished();
}
public void toggleRecording()
{
if(isRecording())
{
stopRecording();
}
else
{
startRecording();
}
}
//Undefined time recording
public void startRecording()
{
record("Capture_"+ZonedDateTime.now().format(FILE_FORMAT)+".gif", 15, Integer.MAX_VALUE);
}
public void record(String fileName, int fps, int time)
{
if(recorder == null)
{
File subFolder = new File(folder, ZonedDateTime.now().format(FOLDER_FORMAT));
FileUtils.ensureFolder(subFolder);
recorder = new GifRecorder(new File(subFolder, fileName), fps, time);
}
}
public void stopRecording()
{
if(recorder != null)
{
recorder.finishPic();
recorder = null;
}
}
public void update()
{
if(recorder != null)
{
recorder.tick(imageProvider);
if(recorder.isFinished())
{
recorder.finishPic();
recorder = null;
}
}
}
private BufferedImage getData()
{
buffer.clear();
GL11.glReadBuffer(GL11.GL_FRONT);
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
for(int x = 0;x < width;x++)
{
for(int y = 0;y < height;y++)
{
int i = (x + (width * y)) * 4;
int r = buffer.get(i) & 0xFF;
int g = buffer.get(i + 1) & 0xFF;
int b = buffer.get(i + 2) & 0xFF;
data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b;
}
}
return image;
}
public BufferedImage getScreenShot()
{
buffer.clear();
GL11.glReadBuffer(GL11.GL_FRONT);
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
for(int x = 0;x < width;x++)
{
for(int y = 0;y < height;y++)
{
int i = (x + (width * y)) * 4;
int r = buffer.get(i) & 0xFF;
int g = buffer.get(i + 1) & 0xFF;
int b = buffer.get(i + 2) & 0xFF;
data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b;
}
}
return image;
}
public void cleanup()
{
if(buffer != null)
{
MemoryUtil.memFree(buffer);
buffer = null;
}
}
public static class GifRecorder
{
GifWriter writer;
long timeBetweenFrames;
long lastTime = -1L;
long freeTime;
int totalPics;
public GifRecorder(File file, int fps, int time)
{
int ms = 1000 / fps;
writer = GifWriter.create(file, BufferedImage.TYPE_INT_ARGB, ms);
timeBetweenFrames = ms * 1000000L;
freeTime = ms * 1000000L;
totalPics = fps * time;
}
public void tick(Supplier<BufferedImage> supply)
{
if(lastTime == -1L)
{
totalPics--;
insert(supply.get());
lastTime = System.nanoTime();
return;
}
long time = System.nanoTime();
long happend = time - lastTime;
lastTime = time;
freeTime -= happend;
if(freeTime <= 0)
{
freeTime += timeBetweenFrames;
insert(supply.get());
totalPics--;
}
}
private void insert(final BufferedImage newBuffer)
{
FACTORY.execute(new Runnable(){
BufferedImage buffer = newBuffer;
@Override
public void run()
{
if(writer != null)
{
writer.insertPicture(buffer);
}
}
});
}
public boolean isFinished()
{
return totalPics <= 0;
}
public void finishPic()
{
FACTORY.execute(new Runnable(){
@Override
public void run()
{
writer.close();
writer = null;
}
});
}
}
}

View File

@ -1,37 +1,44 @@
package speiger.src.coreengine.rendering.utils.states;
import org.lwjgl.opengl.GL11;
public class BlendState extends GLState
{
int src;
int func;
public BlendState()
{
super(GL11.GL_BLEND, false);
}
@Override
public BlendState push(boolean newValue)
{
super.push(newValue);
return this;
}
public BlendState setFunction(int src, int func)
{
if(this.src != src && this.func != func)
{
this.src = src;
this.func = func;
GL11.glBlendFunc(src, func);
}
return this;
}
public void setDefault()
{
setFunction(GL11.GL_ONE, GL11.GL_ONE);
}
}
package speiger.src.coreengine.rendering.utils.states;
import org.lwjgl.opengl.GL11;
public class BlendState extends GLState
{
int src;
int func;
public BlendState()
{
super(GL11.GL_BLEND, false);
}
@Override
public BlendState push(boolean newValue)
{
super.push(newValue);
return this;
}
public BlendState setFunction(int src, int func)
{
if(this.src != src && this.func != func)
{
this.src = src;
this.func = func;
GL11.glBlendFunc(src, func);
}
return this;
}
@Override
public void reapply()
{
super.reapply();
GL11.glBlendFunc(src, func);
}
public void setDefault()
{
setFunction(GL11.GL_ONE, GL11.GL_ONE);
}
}

View File

@ -1,33 +1,40 @@
package speiger.src.coreengine.rendering.utils.states;
import org.lwjgl.opengl.GL11;
public class CullState extends GLState
{
int type;
public CullState(int defaultState)
{
super(GL11.GL_CULL_FACE, false);
type = defaultState;
}
@Override
public CullState push(boolean newValue)
{
super.push(newValue);
return this;
}
public void setCullType(int type)
{
if(this.type != type)
{
this.type = type;
if(lastState)
{
GL11.glCullFace(type);
}
}
}
}
package speiger.src.coreengine.rendering.utils.states;
import org.lwjgl.opengl.GL11;
public class CullState extends GLState
{
int type;
public CullState(int defaultState)
{
super(GL11.GL_CULL_FACE, false);
type = defaultState;
}
@Override
public CullState push(boolean newValue)
{
super.push(newValue);
return this;
}
public void setCullType(int type)
{
if(this.type != type)
{
this.type = type;
if(lastState)
{
GL11.glCullFace(type);
}
}
}
@Override
public void reapply()
{
super.reapply();
GL11.glCullFace(type);
}
}

View File

@ -1,58 +1,59 @@
package speiger.src.coreengine.rendering.utils.states;
import speiger.src.collections.floats.lists.FloatArrayList;
import speiger.src.collections.floats.lists.FloatList;
public abstract class FloatState implements IGLState
{
protected final float defaultValue;
protected FloatList states = new FloatArrayList();
public FloatState(float defaultValue)
{
this.defaultValue = defaultValue;
}
public void push(float newValue)
{
if((states.isEmpty() && equalsNot(newValue, defaultValue)) || (states.size() > 0 && equalsNot(states.getFloat(states.size()-1), newValue)))
{
setValue(newValue);
}
states.add(newValue);
}
public void pop()
{
if(states.isEmpty()) throw new IllegalStateException("State is already reset");
if(states.size() == 1 && equalsNot(defaultValue, states.getFloat(0)))
{
setValue(defaultValue);
}
else if(states.size() > 1 && equalsNot(states.getFloat(states.size()-2), states.getFloat(states.size()-1)))
{
setValue(states.getFloat(states.size()-2));
}
states.removeFloat(states.size()-1);
}
protected abstract void setValue(float value);
protected abstract String getName();
protected boolean equalsNot(float key, float value)
{
return Float.floatToIntBits(key) != Float.floatToIntBits(value);
}
@Override
public void cleanup()
{
if(states.size() > 1)
{
float value = states.getFloat(states.size()-1);
states.clear();
states.add(value);
}
}
}
package speiger.src.coreengine.rendering.utils.states;
import speiger.src.collections.floats.collections.FloatStack;
import speiger.src.collections.floats.lists.FloatArrayList;
public abstract class FloatState implements IGLState
{
protected final float defaultValue;
protected FloatStack states = new FloatArrayList();
public FloatState(float defaultValue)
{
this.defaultValue = defaultValue;
}
public void push(float newValue)
{
if((states.isEmpty() && equalsNot(newValue, defaultValue)) || (states.size() > 0 && equalsNot(states.top(), newValue)))
{
setValue(newValue);
}
states.push(newValue);
}
public void pop()
{
if(states.isEmpty()) throw new IllegalStateException("State is already reset");
float prev = states.pop();
if(states.isEmpty() && equalsNot(defaultValue, prev)) setValue(defaultValue);
else if(!states.isEmpty() && equalsNot(states.top(), prev)) setValue(states.top());
}
protected abstract void setValue(float value);
protected abstract String getName();
protected boolean equalsNot(float key, float value)
{
return Float.floatToIntBits(key) != Float.floatToIntBits(value);
}
@Override
public void reapply()
{
if(states.isEmpty()) setValue(defaultValue);
else setValue(states.top());
}
@Override
public void cleanup()
{
if(states.size() > 1)
{
float value = states.top();
states.clear();
states.push(value);
}
}
}

View File

@ -1,65 +1,72 @@
package speiger.src.coreengine.rendering.utils.states;
import java.util.BitSet;
import org.lwjgl.opengl.GL11;
public class GLState implements IGLState
{
final int id;
protected final boolean defaultValue;
protected final BitSet memory = new BitSet();
protected int index = -1;
protected boolean lastState;
public GLState(int id, boolean defaultValue)
{
this.id = id;
this.defaultValue = defaultValue;
}
public GLState push(boolean newValue)
{
if((index < 0 && newValue != defaultValue) || (index >= 0 && memory.get(index) != newValue))
{
setValue(newValue);
}
memory.set(++index, newValue);
return this;
}
public void pop()
{
if(index < 0) throw new IllegalStateException("State is already reset");
if(index == 0 && defaultValue != memory.get(0))
{
setValue(defaultValue);
}
else if(index > 0 && memory.get(index-1) != memory.get(index))
{
setValue(memory.get(index-1));
}
index--;
}
public boolean isEnabled()
{
return index < 0 ? defaultValue : memory.get(index);
}
protected void setValue(boolean value)
{
if(value) GL11.glEnable(id);
else GL11.glDisable(id);
}
@Override
public void cleanup()
{
if(index > 0)
{
memory.set(0, memory.get(index));
index = 0;
}
}
}
package speiger.src.coreengine.rendering.utils.states;
import java.util.BitSet;
import org.lwjgl.opengl.GL11;
public class GLState implements IGLState
{
final int id;
protected final boolean defaultValue;
protected final BitSet memory = new BitSet();
protected int index = -1;
protected boolean lastState;
public GLState(int id, boolean defaultValue)
{
this.id = id;
this.defaultValue = defaultValue;
}
public GLState push(boolean newValue)
{
if((index < 0 && newValue != defaultValue) || (index >= 0 && memory.get(index) != newValue))
{
setValue(newValue);
}
memory.set(++index, newValue);
return this;
}
public void pop()
{
if(index < 0) throw new IllegalStateException("State is already reset");
if(index == 0 && defaultValue != memory.get(0))
{
setValue(defaultValue);
}
else if(index > 0 && memory.get(index-1) != memory.get(index))
{
setValue(memory.get(index-1));
}
index--;
}
public boolean isEnabled()
{
return index < 0 ? defaultValue : memory.get(index);
}
protected void setValue(boolean value)
{
if(value) GL11.glEnable(id);
else GL11.glDisable(id);
}
@Override
public void reapply()
{
if(index < 0) setValue(defaultValue);
else setValue(memory.get(index));
}
@Override
public void cleanup()
{
if(index > 0)
{
memory.set(0, memory.get(index));
index = 0;
}
}
}

View File

@ -1,6 +1,7 @@
package speiger.src.coreengine.rendering.utils.states;
public interface IGLState
{
public void cleanup();
}
package speiger.src.coreengine.rendering.utils.states;
public interface IGLState
{
public void cleanup();
public void reapply();
}

View File

@ -1,76 +1,80 @@
package speiger.src.coreengine.utils.collections.pools;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.function.Supplier;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.coreengine.utils.functions.Functions;
public class ThreadPool<T> implements IPool<T>
{
int cap;
ObjectList<T> stack;
Supplier<T> creator;
Consumer<T> acceptor;
public ThreadPool(int size, Supplier<T> creator)
{
this(size, creator, Functions.getVoidConsumer());
}
public ThreadPool(int size, Supplier<T> creator, Consumer<T> acceptor)
{
cap = size;
stack = new ObjectArrayList<T>(size);
this.creator = creator;
this.acceptor = acceptor;
}
@Override
public synchronized void accept(T t)
{
if(stack.size() < cap)
{
stack.add(t);
acceptor.accept(t);
}
}
@Override
public synchronized void accept(T[] array)
{
stack.addAll(array, 0, Math.min(array.length, cap - stack.size()));
for(int i = 0,m=Math.min(array.length, cap - stack.size());i<m;acceptor.accept(array[i++]));
}
@Override
public synchronized void accept(Collection<T> array)
{
Iterator<T> iter = array.iterator();
for(int i = 0,m=Math.min(array.size(), cap - stack.size());i<m && iter.hasNext();i++)
{
T next = iter.next();
stack.add(next);
acceptor.accept(next);
}
}
@Override
public synchronized T get()
{
return stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1);
}
@Override
public synchronized T[] get(T[] array)
{
for(int i = 0,m=array.length;i<m;i++)
{
array[i] = stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1);
}
return array;
}
}
package speiger.src.coreengine.utils.collections.pools;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.function.Supplier;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.coreengine.utils.functions.Functions;
public class ThreadPool<T> implements IPool<T>
{
int cap;
ObjectList<T> stack;
Supplier<T> creator;
Consumer<T> acceptor;
public ThreadPool(int size, Supplier<T> creator)
{
this(size, creator, Functions.getVoidConsumer());
}
public ThreadPool(int size, Supplier<T> creator, Consumer<T> acceptor)
{
cap = size;
stack = new ObjectArrayList<T>(size);
this.creator = creator;
this.acceptor = acceptor;
}
@Override
public synchronized void accept(T t)
{
if(stack.size() < cap)
{
stack.add(t);
acceptor.accept(t);
}
}
@Override
public synchronized void accept(T[] array)
{
int size = Math.min(array.length, cap - stack.size());
if(size <= 0) return;
stack.addAll(array, 0, size);
for(int i = 0;i<size;acceptor.accept(array[i++]));
}
@Override
public synchronized void accept(Collection<T> array)
{
int size = Math.min(array.size(), cap - stack.size());
if(size <= 0) return;
Iterator<T> iter = array.iterator();
for(int i = 0;i<size && iter.hasNext();i++)
{
T next = iter.next();
stack.add(next);
acceptor.accept(next);
}
}
@Override
public synchronized T get()
{
return stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1);
}
@Override
public synchronized T[] get(T[] array)
{
for(int i = 0,m=array.length;i<m;i++)
{
array[i] = stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1);
}
return array;
}
}

View File

@ -1,151 +1,151 @@
package speiger.src.coreengine.utils.profiler;
import java.util.ArrayList;
import java.util.List;
import speiger.src.collections.longs.queues.LongArrayFIFOQueue;
import speiger.src.collections.longs.queues.LongPriorityQueue;
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
import speiger.src.coreengine.rendering.utils.GLStamper;
import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
public class GPUProfilerEntry implements IProfilerEntry
{
String name;
String pathName;
IProfiler owner;
IProfilerEntry parent;
List<IProfilerEntry> children = new ArrayList<IProfilerEntry>();
int debth = 0;
int totalTicks = 0;
long maxTime = Long.MIN_VALUE;
long minTime = Long.MAX_VALUE;
long average = 0L;
LongPriorityQueue entries = new LongArrayFIFOQueue();
long startTime = 0L;
long currentTime = 0L;
ObjectPriorityDequeue<GLStamp> stamps = new ObjectArrayFIFOQueue<GLStamp>();
public GPUProfilerEntry(String name, IProfiler owner)
{
this.name = name;
pathName = name;
this.owner = owner;
}
public void addChild(GPUProfilerEntry child)
{
if(child != null)
{
children.add(child);
child.setParent(this);
}
}
private void setParent(GPUProfilerEntry parent)
{
this.parent = parent;
debth = parent.debth + 1;
pathName = parent.pathName+"/"+name;
}
public void start()
{
stamps.enqueue(GLStamper.INSTANCE.createStamp(owner.getName()).start());
}
public void stop()
{
stamps.last().stop();
}
public void onFrameFinished(boolean end)
{
while(!stamps.isEmpty() && stamps.first().isFinished())
{
GLStamp stamp = stamps.dequeue();
currentTime += stamp.getResult();
stamp.release();
}
average += currentTime;
entries.enqueue(currentTime);
if(entries.size() > 20)
{
average -= entries.dequeue();
}
currentTime = average / entries.size();
minTime = Math.min(minTime, currentTime);
maxTime = Math.max(maxTime, currentTime);
currentTime = 0;
if(end && totalTicks++ >= 10)
{
minTime = currentTime;
maxTime = currentTime;
totalTicks = 0;
}
}
@Override
public String getName()
{
return name;
}
@Override
public String getPathName()
{
return pathName;
}
@Override
public int getDebth()
{
return debth;
}
@Override
public IProfiler getOwner()
{
return owner;
}
@Override
public IProfilerEntry getParent()
{
return parent;
}
@Override
public int getChildCount()
{
return children.size();
}
@Override
public IProfilerEntry getChild(int index)
{
return children.get(index);
}
@Override
public long getMinTime()
{
return minTime;
}
@Override
public long getNanoTime()
{
return entries.isEmpty() ? 0L : average / entries.size();
}
@Override
public long getMaxTime()
{
return maxTime;
}
}
package speiger.src.coreengine.utils.profiler;
import java.util.ArrayList;
import java.util.List;
import speiger.src.collections.longs.queues.LongArrayFIFOQueue;
import speiger.src.collections.longs.queues.LongPriorityQueue;
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
import speiger.src.coreengine.rendering.utils.GLStamper;
import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
public class GPUProfilerEntry implements IProfilerEntry
{
String name;
String pathName;
IProfiler owner;
IProfilerEntry parent;
List<IProfilerEntry> children = new ArrayList<IProfilerEntry>();
int debth = 0;
int totalTicks = 0;
long maxTime = Long.MIN_VALUE;
long minTime = Long.MAX_VALUE;
long average = 0L;
LongPriorityQueue entries = new LongArrayFIFOQueue();
long startTime = 0L;
long currentTime = 0L;
ObjectPriorityDequeue<GLStamp> stamps = new ObjectArrayFIFOQueue<GLStamp>();
public GPUProfilerEntry(String name, IProfiler owner)
{
this.name = name;
pathName = name;
this.owner = owner;
}
public void addChild(GPUProfilerEntry child)
{
if(child != null)
{
children.add(child);
child.setParent(this);
}
}
private void setParent(GPUProfilerEntry parent)
{
this.parent = parent;
debth = parent.debth + 1;
pathName = parent.pathName+"/"+name;
}
public void start()
{
stamps.enqueue(GLStamper.INSTANCE.createStamp(owner.getName()).start());
}
public void stop()
{
stamps.last().stop();
}
public void onFrameFinished(boolean end)
{
while(!stamps.isEmpty() && stamps.first().isFinished())
{
GLStamp stamp = stamps.dequeue();
currentTime += stamp.getResult();
stamp.release();
}
average += currentTime;
entries.enqueue(currentTime);
if(entries.size() > 100)
{
average -= entries.dequeue();
}
currentTime = average / entries.size();
minTime = Math.min(minTime, currentTime);
maxTime = Math.max(maxTime, currentTime);
currentTime = 0;
if(end && totalTicks++ >= 10)
{
minTime = currentTime;
maxTime = currentTime;
totalTicks = 0;
}
}
@Override
public String getName()
{
return name;
}
@Override
public String getPathName()
{
return pathName;
}
@Override
public int getDebth()
{
return debth;
}
@Override
public IProfiler getOwner()
{
return owner;
}
@Override
public IProfilerEntry getParent()
{
return parent;
}
@Override
public int getChildCount()
{
return children.size();
}
@Override
public IProfilerEntry getChild(int index)
{
return children.get(index);
}
@Override
public long getMinTime()
{
return minTime;
}
@Override
public long getNanoTime()
{
return entries.isEmpty() ? 0L : average / entries.size();
}
@Override
public long getMaxTime()
{
return maxTime;
}
}

View File

@ -1,163 +1,161 @@
package speiger.src.coreengine.utils.profiler;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.ObjIntConsumer;
import speiger.src.coreengine.utils.helpers.TextUtil;
public interface IProfiler
{
public String getName();
public IProfilerEntry getEntry(String name);
public long getTicksRan();
public void enable();
public void disable();
public default void setState(boolean enabled)
{
if(enabled)
{
enable();
return;
}
disable();
}
public boolean isEnabled();
public void addListener(ObjIntConsumer<IProfiler> listener);
public void removeListener(ObjIntConsumer<IProfiler> listener);
public IProfiler start(String name);
public IProfiler start(Class<?> clz);
public IProfiler stop();
public IProfiler next(String name);
public void onFrameEnded(boolean count);
public static interface IProfilerEntry
{
public String getName();
public default String getPathName()
{
return getName();
}
public long getMinTime();
public long getNanoTime();
public long getMaxTime();
public int getDebth();
public int getChildCount();
public IProfilerEntry getChild(int index);
public IProfilerEntry getParent();
public IProfiler getOwner();
default long getTotalTime()
{
IProfilerEntry entry = this;
while(entry.getParent() != null)
{
entry = entry.getParent();
}
return entry.getNanoTime();
}
public default List<ProfilerData> getData()
{
List<ProfilerData> list = new ArrayList<ProfilerData>();
long time = getNanoTime();
long totalTime = getTotalTime();
long used = 0L;
for(int i = 0;i<getChildCount();i++)
{
IProfilerEntry child = getChild(i);
long nanoTime = child.getNanoTime();
used += nanoTime;
double percent = (((double)nanoTime / (double)time) * 100D);
double totalPercent = (((double)nanoTime / (double)totalTime) * 100D);
list.add(new ProfilerData(child.getName(), nanoTime, percent, totalPercent));
}
if(used < time)
{
long nanoTime = time - used;
double percent = (((double)nanoTime / (double)time) * 100D);
double totalPercent = (((double)nanoTime / (double)totalTime) * 100D);
list.add(new ProfilerData("Nameless", nanoTime, percent, totalPercent));
}
Collections.sort(list);
return list;
}
}
public static class ProfilerData implements Comparable<ProfilerData>
{
String name;
int color;
long nanoTime;
double effect;
double totalEffect;
public ProfilerData(String name, long time, double effect, double totalEffect)
{
this.name = name;
color = TextUtil.getColorFromText(name);
nanoTime = time;
this.effect = effect;
this.totalEffect = totalEffect;
}
@Override
public int compareTo(ProfilerData o)
{
if(o.nanoTime > nanoTime)
{
return 1;
}
return o.nanoTime < nanoTime ? -1 : name.compareTo(o.name);
}
public String getName()
{
return name;
}
public int getColor()
{
return color;
}
public long getNanoTime()
{
return nanoTime;
}
public double getEffect()
{
return effect;
}
public double getTotalEffect()
{
return totalEffect;
}
}
}
package speiger.src.coreengine.utils.profiler;
import java.util.function.ObjIntConsumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.coreengine.utils.helpers.TextUtil;
public interface IProfiler
{
public String getName();
public IProfilerEntry getEntry(String name);
public long getTicksRan();
public void enable();
public void disable();
public default void setState(boolean enabled)
{
if(enabled)
{
enable();
return;
}
disable();
}
public boolean isEnabled();
public void addListener(ObjIntConsumer<IProfiler> listener);
public void removeListener(ObjIntConsumer<IProfiler> listener);
public IProfiler start(String name);
public IProfiler start(Class<?> clz);
public IProfiler stop();
public IProfiler next(String name);
public void onFrameEnded(boolean count);
public static interface IProfilerEntry
{
public String getName();
public default String getPathName()
{
return getName();
}
public long getMinTime();
public long getNanoTime();
public long getMaxTime();
public int getDebth();
public int getChildCount();
public IProfilerEntry getChild(int index);
public IProfilerEntry getParent();
public IProfiler getOwner();
default long getTotalTime()
{
IProfilerEntry entry = this;
while(entry.getParent() != null)
{
entry = entry.getParent();
}
return entry.getNanoTime();
}
public default ObjectList<ProfilerData> getData()
{
ObjectList<ProfilerData> list = new ObjectArrayList<>();
long time = getNanoTime();
long totalTime = getTotalTime();
long used = 0L;
for(int i = 0;i<getChildCount();i++)
{
IProfilerEntry child = getChild(i);
long nanoTime = child.getNanoTime();
used += nanoTime;
double percent = (((double)nanoTime / (double)time) * 100D);
double totalPercent = (((double)nanoTime / (double)totalTime) * 100D);
list.add(new ProfilerData(child.getName(), nanoTime, percent, totalPercent));
}
if(used < time)
{
long nanoTime = time - used;
double percent = (((double)nanoTime / (double)time) * 100D);
double totalPercent = (((double)nanoTime / (double)totalTime) * 100D);
list.add(new ProfilerData("self", nanoTime, percent, totalPercent));
}
list.sort(null);
return list;
}
}
public static class ProfilerData implements Comparable<ProfilerData>
{
String name;
int color;
long nanoTime;
double effect;
double totalEffect;
public ProfilerData(String name, long time, double effect, double totalEffect)
{
this.name = name;
color = TextUtil.getColorFromText(name);
nanoTime = time;
this.effect = effect;
this.totalEffect = totalEffect;
}
@Override
public int compareTo(ProfilerData o)
{
if(o.nanoTime > nanoTime)
{
return 1;
}
return o.nanoTime < nanoTime ? -1 : name.compareTo(o.name);
}
public String getName()
{
return name;
}
public int getColor()
{
return color;
}
public long getNanoTime()
{
return nanoTime;
}
public double getEffect()
{
return effect;
}
public double getTotalEffect()
{
return totalEffect;
}
}
}

View File

@ -1,152 +1,152 @@
package speiger.src.coreengine.utils.profiler;
import java.util.ArrayList;
import java.util.List;
import speiger.src.collections.longs.queues.LongArrayFIFOQueue;
import speiger.src.collections.longs.queues.LongPriorityQueue;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
public class ProfilerEntry implements IProfilerEntry
{
String name;
String pathName;
IProfiler owner;
IProfilerEntry parent;
List<IProfilerEntry> children = new ArrayList<IProfilerEntry>();
int debth = 0;
int totalTicks = 0;
long maxTime = Long.MIN_VALUE;
long minTime = Long.MAX_VALUE;
long average = 0L;
LongPriorityQueue entries = new LongArrayFIFOQueue();
long startTime = 0L;
long currentTime = 0L;
boolean didTick = false;
public ProfilerEntry(String name, IProfiler owner)
{
this.name = name;
pathName = name;
this.owner = owner;
}
public void addChild(ProfilerEntry child)
{
if(child != null)
{
children.add(child);
child.setParent(this);
}
}
private void setParent(ProfilerEntry parent)
{
this.parent = parent;
debth = parent.debth + 1;
pathName = parent.pathName+"/"+name;
}
public void start()
{
startTime = System.nanoTime();
}
public void stop()
{
currentTime += (System.nanoTime() - startTime);
didTick = true;
}
public void onFrameFinished(boolean end)
{
if(!didTick)
{
if(end && totalTicks++ >= 10)
{
minTime = 0;
maxTime = 0;
totalTicks = 0;
}
return;
}
didTick = false;
average += currentTime;
entries.enqueue(currentTime);
if(entries.size() > 20)
{
average -= entries.dequeue();
}
currentTime = average / entries.size();
minTime = Math.min(minTime, currentTime);
maxTime = Math.max(maxTime, currentTime);
currentTime = 0;
if(end && totalTicks++ >= 10)
{
minTime = currentTime;
maxTime = currentTime;
totalTicks = 0;
}
}
@Override
public String getName()
{
return name;
}
@Override
public String getPathName()
{
return pathName;
}
@Override
public long getMinTime()
{
return minTime;
}
@Override
public long getNanoTime()
{
return entries.isEmpty() ? 0L : average / entries.size();
}
@Override
public long getMaxTime()
{
return maxTime;
}
@Override
public int getDebth()
{
return debth;
}
@Override
public int getChildCount()
{
return children.size();
}
@Override
public IProfilerEntry getChild(int index)
{
return children.get(index);
}
@Override
public IProfilerEntry getParent()
{
return parent;
}
@Override
public IProfiler getOwner()
{
return owner;
}
}
package speiger.src.coreengine.utils.profiler;
import java.util.ArrayList;
import java.util.List;
import speiger.src.collections.longs.queues.LongArrayFIFOQueue;
import speiger.src.collections.longs.queues.LongPriorityQueue;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
public class ProfilerEntry implements IProfilerEntry
{
String name;
String pathName;
IProfiler owner;
IProfilerEntry parent;
List<IProfilerEntry> children = new ArrayList<IProfilerEntry>();
int debth = 0;
int totalTicks = 0;
long maxTime = Long.MIN_VALUE;
long minTime = Long.MAX_VALUE;
long average = 0L;
LongPriorityQueue entries = new LongArrayFIFOQueue();
long startTime = 0L;
long currentTime = 0L;
boolean didTick = false;
public ProfilerEntry(String name, IProfiler owner)
{
this.name = name;
pathName = name;
this.owner = owner;
}
public void addChild(ProfilerEntry child)
{
if(child != null)
{
children.add(child);
child.setParent(this);
}
}
private void setParent(ProfilerEntry parent)
{
this.parent = parent;
debth = parent.debth + 1;
pathName = parent.pathName+"/"+name;
}
public void start()
{
startTime = System.nanoTime();
}
public void stop()
{
currentTime += (System.nanoTime() - startTime);
didTick = true;
}
public void onFrameFinished(boolean end)
{
if(!didTick)
{
if(end && totalTicks++ >= 10)
{
minTime = Long.MAX_VALUE;
maxTime = Long.MIN_VALUE;
totalTicks = 0;
}
return;
}
didTick = false;
average += currentTime;
entries.enqueue(currentTime);
if(entries.size() > 100)
{
average -= entries.dequeue();
}
currentTime = average / entries.size();
minTime = Math.min(minTime, currentTime);
maxTime = Math.max(maxTime, currentTime);
currentTime = 0;
if(end && totalTicks++ >= 10)
{
minTime = currentTime;
maxTime = currentTime;
totalTicks = 0;
}
}
@Override
public String getName()
{
return name;
}
@Override
public String getPathName()
{
return pathName;
}
@Override
public long getMinTime()
{
return minTime;
}
@Override
public long getNanoTime()
{
return entries.isEmpty() ? 0L : average / entries.size();
}
@Override
public long getMaxTime()
{
return maxTime;
}
@Override
public int getDebth()
{
return debth;
}
@Override
public int getChildCount()
{
return children.size();
}
@Override
public IProfilerEntry getChild(int index)
{
return children.get(index);
}
@Override
public IProfilerEntry getParent()
{
return parent;
}
@Override
public IProfiler getOwner()
{
return owner;
}
}

View File

@ -1,146 +1,146 @@
package speiger.src.coreengine.utils.tasks;
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
import speiger.src.collections.objects.utils.ObjectPriorityQueues;
import speiger.src.coreengine.utils.counters.timers.CountdownSync;
public class MainThreadTaskProcessor
{
ObjectPriorityDequeue<ITask> tasks = ObjectPriorityQueues.synchronize(new ObjectArrayFIFOQueue<ITask>());
Watchdog watch;
Thread watchThread;
boolean running = false;
long timeout;
public MainThreadTaskProcessor(long timeout, String name)
{
this.timeout = timeout;
watch = new Watchdog(Thread.currentThread());
watchThread = new Thread(watch, name+"-Thread-Watchdog");
watchThread.start();
}
public void setTimeout(long timeout)
{
this.timeout = timeout;
}
public void addTask(ITask task)
{
tasks.enqueue(task);
}
public void finishAllTasks()
{
if(tasks.isEmpty())
{
return;
}
running = true;
while(!tasks.isEmpty())
{
try
{
tasks.dequeue().execute();
}
catch(InterruptedException e)
{
}
catch(Exception e)
{
e.printStackTrace();
}
}
running = false;
}
public void update()
{
if(tasks.isEmpty())
{
return;
}
watch.unlock();
running = true;
boolean interrupted = false;
while(!tasks.isEmpty() && !(interrupted |= Thread.interrupted()))
{
ITask task = tasks.dequeue();
try
{
task.execute();
}
catch(InterruptedException e)
{
interrupted = true;
}
catch(Exception e)
{
e.printStackTrace();
}
if(!task.isFinished())
{
tasks.enqueue(task);
}
}
running = false;
if(!interrupted)
{
watchThread.interrupt();
}
}
public void kill()
{
if(watchThread != null)
{
return;
}
watch.alive = false;
watchThread.interrupt();
watchThread = null;
}
class Watchdog implements Runnable
{
Thread owner;
boolean alive = true;
CountdownSync timer = new CountdownSync();
Object lock = new Object();
public Watchdog(Thread thread)
{
owner = thread;
}
@Override
public void run()
{
while(alive)
{
try
{
synchronized(lock)
{
lock.wait();
}
timer.sync(timeout);
if(running)
{
owner.interrupt();
}
}
catch(InterruptedException e) {}
}
}
public void unlock()
{
synchronized(lock)
{
lock.notify();
}
}
}
}
package speiger.src.coreengine.utils.tasks;
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
import speiger.src.collections.objects.utils.ObjectPriorityQueues;
import speiger.src.coreengine.utils.counters.timers.CountdownSync;
public class MainThreadTaskProcessor
{
ObjectPriorityDequeue<ITask> tasks = ObjectPriorityQueues.synchronize(new ObjectArrayFIFOQueue<>());
Watchdog watch;
Thread watchThread;
boolean running = false;
long timeout;
public MainThreadTaskProcessor(long timeout, String name)
{
this.timeout = timeout;
watch = new Watchdog(Thread.currentThread());
watchThread = new Thread(watch, name+"-Thread-Watchdog");
watchThread.start();
}
public void setTimeout(long timeout)
{
this.timeout = timeout;
}
public void addTask(ITask task)
{
tasks.enqueue(task);
}
public void finishAllTasks()
{
if(tasks.isEmpty())
{
return;
}
running = true;
while(!tasks.isEmpty())
{
try
{
tasks.dequeue().execute();
}
catch(InterruptedException e)
{
}
catch(Exception e)
{
e.printStackTrace();
}
}
running = false;
}
public void update()
{
if(tasks.isEmpty())
{
return;
}
watch.unlock();
running = true;
boolean interrupted = false;
while(!tasks.isEmpty() && !(interrupted |= Thread.interrupted()))
{
ITask task = tasks.dequeue();
try
{
task.execute();
}
catch(InterruptedException e)
{
interrupted = true;
}
catch(Exception e)
{
e.printStackTrace();
}
if(!task.isFinished())
{
tasks.enqueue(task);
}
}
running = false;
if(!interrupted)
{
watchThread.interrupt();
}
}
public void kill()
{
if(watchThread != null)
{
return;
}
watch.alive = false;
watchThread.interrupt();
watchThread = null;
}
class Watchdog implements Runnable
{
Thread owner;
boolean alive = true;
CountdownSync timer = new CountdownSync();
Object lock = new Object();
public Watchdog(Thread thread)
{
owner = thread;
}
@Override
public void run()
{
while(alive)
{
try
{
synchronized(lock)
{
lock.wait();
}
timer.sync(timeout);
if(running)
{
owner.interrupt();
}
}
catch(InterruptedException e) {}
}
}
public void unlock()
{
synchronized(lock)
{
lock.notify();
}
}
}
}