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

View File

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

View File

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

View File

@ -1,63 +1,73 @@
package speiger.src.coreengine.rendering.gui.components; package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent; import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent; import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains; import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
public class ButtonComponent extends GuiComponent implements IButtonComponent public class ButtonComponent extends GuiComponent implements IButtonComponent
{ {
TextComponent text = new TextComponent(); TextComponent text = new TextComponent();
int color; int color;
public ButtonComponent(String text, int color) public ButtonComponent(String text, int color)
{ {
this(0F, 0F, 0F, 0F, text, color); this(0F, 0F, 0F, 0F, text, color, 1F);
} }
public ButtonComponent(float x, float y, float width, float height, String text, int color) public ButtonComponent(String text, int color, float textScale)
{ {
super(x, y, width, height); this(0F, 0F, 0F, 0F, text, color, textScale);
this.text.setText(text); }
this.color = color;
setFlag(FLAG_SUPPORT_BINDING); public ButtonComponent(float x, float y, float width, float height, String text, int color)
} {
this(x, y, width, height, text, color, 1F);
@Override }
public void init()
{ public ButtonComponent(float x, float y, float width, float height, String text, int color, float textScale)
addChild(text, Constrains.parent()); {
} super(x, y, width, height);
this.text.setText(text).setTextScale(textScale);
public TextComponent getText() this.color = color;
{ setFlag(FLAG_SUPPORT_BINDING);
return text; }
}
@Override
public ButtonComponent setColor(int color) public void init()
{ {
this.color = color; addChild(text, Constrains.parent());
return this; }
}
public TextComponent getText()
@Override {
public boolean renderSelf(int mouseX, int mouseY, float particalTicks) return text;
{ }
float brigthness = getBrightness(mouseX, mouseY);
getRenderer().setBrightness(brigthness).drawQuad(getBox(), color); public ButtonComponent setColor(int color)
text.setBrightness(brigthness); {
return true; this.color = color;
} return this;
}
@Override
public void onRelease(int button, int mouseX, int mouseY) @Override
{ public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
notifyListeners(LISTENER_USER_ACTION); {
} float brigthness = getBrightness(mouseX, mouseY);
getRenderer().setBrightness(brigthness).drawQuad(getBox(), color);
@Override text.setBrightness(brigthness);
protected boolean onUserKey() return true;
{ }
notifyListeners(LISTENER_USER_ACTION);
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; package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.rendering.gui.GuiComponent; import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent; import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.components.misc.ICheckBox; import speiger.src.coreengine.rendering.gui.components.misc.ICheckBox;
import speiger.src.coreengine.rendering.gui.helper.UIShapes; import speiger.src.coreengine.rendering.gui.helper.UIShapes;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer; import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
public class CheckBoxComponent extends GuiComponent implements IButtonComponent, ICheckBox<CheckBoxComponent> public class CheckBoxComponent extends GuiComponent implements IButtonComponent, ICheckBox<CheckBoxComponent>
{ {
boolean isChecked = false; boolean isChecked = false;
int color; int color;
RenderBuffer buffer; RenderBuffer buffer;
public CheckBoxComponent(int color) public CheckBoxComponent(int color)
{ {
super(0F, 0F, 0F, 0F); super(0F, 0F, 0F, 0F);
setFlag(FLAG_SUPPORT_BINDING); setFlag(FLAG_SUPPORT_BINDING);
this.color = color; this.color = color;
} }
public CheckBoxComponent(int color, boolean checked) public CheckBoxComponent(int color, boolean checked)
{ {
super(0F, 0F, 0F, 0F); super(0F, 0F, 0F, 0F);
setFlag(FLAG_SUPPORT_BINDING); setFlag(FLAG_SUPPORT_BINDING);
this.color = color; this.color = color;
} }
public CheckBoxComponent(float x, float y, float width, float height, int color) public CheckBoxComponent(float x, float y, float width, float height, int color)
{ {
super(x, y, width, height); super(x, y, width, height);
setFlag(FLAG_SUPPORT_BINDING); setFlag(FLAG_SUPPORT_BINDING);
this.color = color; this.color = color;
} }
public CheckBoxComponent(float x, float y, float width, float height, int color, boolean checked) public CheckBoxComponent(float x, float y, float width, float height, int color, boolean checked)
{ {
super(x, y, width, height); super(x, y, width, height);
setFlag(FLAG_SUPPORT_BINDING); setFlag(FLAG_SUPPORT_BINDING);
this.color = color; this.color = color;
isChecked = checked; isChecked = checked;
} }
@Override @Override
public void init() public void init()
{ {
addCloseListener(buffer = getRenderer().createBuffer()); onClose(buffer = getRenderer().createBuffer());
} }
@Override @Override
public final CheckBoxComponent setChecked(boolean isChecked) public final CheckBoxComponent setChecked(boolean isChecked)
{ {
this.isChecked = isChecked; this.isChecked = isChecked;
return this; return this;
} }
public final CheckBoxComponent setColor(int color) public final CheckBoxComponent setColor(int color)
{ {
if(this.color != color) if(this.color != color)
{ {
this.color = color; this.color = color;
onChanged(true); onChanged(true);
} }
return this; return this;
} }
@Override @Override
public boolean isChecked() public boolean isChecked()
{ {
return isChecked; return isChecked;
} }
@Override @Override
protected void repaint() protected void repaint()
{ {
float width = getBox().getWidth(); float width = getBox().getWidth();
float height = getBox().getHeight(); float height = getBox().getHeight();
buffer.clear(); buffer.clear();
UIShapes.createCross(buffer, width, height, (width / 3.3F), (height / 5F), color); UIShapes.createCross(buffer, width, height, (width / 3.3F), (height / 5F), color);
UIShapes.createCross(buffer, width, height, (width / 5F), (height / 10F), color); UIShapes.createCross(buffer, width, height, (width / 5F), (height / 10F), color);
} }
@Override @Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks) public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{ {
float brightness = getActiveBrightness(); float brightness = getActiveBrightness();
float centerX = getBox().getCenterX(); float centerX = getBox().getCenterX();
float centerY = getBox().getCenterY(); float centerY = getBox().getCenterY();
getRenderer().setBrightness(brightness).drawQuad(getBox(), color).setBrightness(brightness * 0.8F).drawFrame(getBox(), color).translate(centerX, centerY); getRenderer().setBrightness(brightness).drawQuad(getBox(), color).setBrightness(brightness * 0.8F).drawFrame(getBox(), color).translate(centerX, centerY);
if(isChecked()) 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); 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)) 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(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); getRenderer().setBrightness(1F).translate(-centerX, -centerY);
return true; return true;
} }
@Override @Override
public boolean onClick(int button, int mouseX, int mouseY) public boolean onClick(int button, int mouseX, int mouseY)
{ {
return true; return true;
} }
@Override @Override
public void onRelease(int button, int mouseX, int mouseY) public void onRelease(int button, int mouseX, int mouseY)
{ {
isChecked = !isChecked; isChecked = !isChecked;
notifyListeners(LISTENER_USER_ACTION); notifyListeners(LISTENER_USER_ACTION);
} }
@Override @Override
protected boolean onUserKey() protected boolean onUserKey()
{ {
isChecked = !isChecked; isChecked = !isChecked;
notifyListeners(LISTENER_USER_ACTION); notifyListeners(LISTENER_USER_ACTION);
return true; return true;
} }
} }

View File

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

View File

@ -1,122 +1,159 @@
package speiger.src.coreengine.rendering.gui.components; package speiger.src.coreengine.rendering.gui.components;
import java.util.function.IntFunction; import java.util.function.IntFunction;
import java.util.function.IntSupplier; import java.util.function.IntSupplier;
import speiger.src.coreengine.rendering.gui.GuiComponent; import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox; 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.box.ParentBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains; import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer; import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
public class ProgressBarComponent extends GuiComponent public class ProgressBarComponent extends GuiComponent
{ {
IGuiBox inner = new ParentBox(1F); IGuiBox inner = new ParentBox(1F);
TextComponent text = new TextComponent(); TextComponent text = new TextComponent();
int color; int color;
int value; int value;
int max; int max;
IntFunction<String> name; IntFunction<String> name;
IntSupplier valueGenerator; IntSupplier valueGenerator;
public ProgressBarComponent(int color, int value, int max) public ProgressBarComponent(int color, int value, int max)
{ {
this(color, value, max, null); this(color, value, max, null);
} }
public ProgressBarComponent(int color, int value, int max, IntFunction<String> name) public ProgressBarComponent(int color, float textScale, int value, int max)
{ {
this(0F, 0F, 0F, 0F, color, value, max, name); this(color, textScale, value, max, null);
} }
public ProgressBarComponent(float x, float y, float width, float height, int color, int value, int max) public ProgressBarComponent(int color, int value, int max, IntFunction<String> name)
{ {
this(x, y, width, height, color, value, max, null); 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, IntFunction<String> name) public ProgressBarComponent(int color, float textScale, int value, int max, IntFunction<String> name)
{ {
super(x, y, width, height); this(0F, 0F, 0F, 0F, color, textScale, value, max, name);
this.name = name; }
setColor(color);
setMax(max); public ProgressBarComponent(float x, float y, float width, float height, int color, int value, int max)
setValue(value); {
} this(x, y, width, height, color, value, max, null);
}
@Override
public void init() public ProgressBarComponent(float x, float y, float width, float height, int color, float textScale, int value, int max)
{ {
addBox(inner); this(x, y, width, height, color, textScale, value, max, null);
text.setZOffset(0.1F); }
text.setText(stringify());
addChild(text, Constrains.parent()); 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 TextComponent getText() }
{
return text; 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);
public ProgressBarComponent setColor(int color) this.name = name;
{ text.setTextScale(textScale);
this.color = color; setColor(color);
return this; setMax(max);
} setValue(value);
}
public ProgressBarComponent setValueGenerator(IntSupplier valueGenerator)
{ @Override
this.valueGenerator = valueGenerator; public void init()
return this; {
} addBox(inner);
text.setZOffset(0.1F);
public ProgressBarComponent setValue(int newValue) text.setText(stringify());
{ addChild(text, Constrains.parent());
if(value != newValue) }
{
value = newValue; public TextComponent getText()
text.setText(stringify()); {
} return text;
return this; }
}
public ProgressBarComponent setColor(int color)
public ProgressBarComponent setMax(int newMax) {
{ this.color = color;
if(max != newMax) return this;
{ }
max = newMax;
if(value > max) setValue(max); public ProgressBarComponent setValueGenerator(IntSupplier valueGenerator)
} {
return this; this.valueGenerator = valueGenerator;
} return this;
}
protected String stringify()
{ public ProgressBarComponent setTextGenerator(IntFunction<String> name)
if(name != null) return name.apply(value); {
else if(max == 0) return "0%"; this.name = name;
return Integer.toString((int)(((float)value / (float)max) * 100F))+"%"; return this;
} }
protected float getProgress() public ProgressBarComponent setValue(int newValue)
{ {
return max == 0 ? 0F : (float)value / (float)max; if(value != newValue)
} {
value = newValue;
@Override text.setText(stringify());
protected boolean fixedUpdateSelf() }
{ return this;
if(valueGenerator != null) setValue(valueGenerator.getAsInt()); }
return true;
} public ProgressBarComponent setMax(int newMax)
{
@Override if(max != newMax)
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks) {
{ max = newMax;
float extra = (inner.getMaxX() - inner.getMinX()) * getProgress(); if(value > max) setValue(max);
UIRenderer render = getRenderer(); }
render.setBrightness(getActiveBrightness() * 0.75F).drawQuad(getBox(), color); return this;
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()); protected String stringify()
return true; {
} 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; package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.math.MathUtils; import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent; import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent; import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox; import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
public class ScrollBarComponent extends GuiComponent implements IButtonComponent public class ScrollBarComponent extends GuiComponent implements IButtonComponent
{ {
public static final int FLAG_HORIZONTAL = 1024; public static final int FLAG_HORIZONTAL = 1 << 20;
public static final int FLAG_INVERTED = 2048; public static final int FLAG_INVERTED = 1 << 21;
int color; int color;
float lastMouse = -1; float lastMouse = -1;
int current; int current;
int max; int max;
public ScrollBarComponent(int color) public ScrollBarComponent(int color)
{ {
super(0F, 0F, 0F, 0F); super(0F, 0F, 0F, 0F);
this.color = color; this.color = color;
} }
public ScrollBarComponent(int color, int max) public ScrollBarComponent(int color, int max)
{ {
super(0F, 0F, 0F, 0F); super(0F, 0F, 0F, 0F);
this.color = color; this.color = color;
this.max = max; this.max = max;
} }
public ScrollBarComponent(int color, int max, int current) public ScrollBarComponent(int color, int max, int current)
{ {
super(0F, 0F, 0F, 0F); super(0F, 0F, 0F, 0F);
this.color = color; this.color = color;
this.max = max; this.max = max;
this.current = current; this.current = current;
} }
public ScrollBarComponent(float x, float y, float width, float height, int color) public ScrollBarComponent(float x, float y, float width, float height, int color)
{ {
super(x, y, width, height); super(x, y, width, height);
this.color = color; this.color = color;
} }
public ScrollBarComponent(float x, float y, float width, float height, int color, int max) public ScrollBarComponent(float x, float y, float width, float height, int color, int max)
{ {
super(x, y, width, height); super(x, y, width, height);
this.color = color; this.color = color;
this.max = max; this.max = max;
} }
public ScrollBarComponent(float x, float y, float width, float height, int color, int max, int current) public ScrollBarComponent(float x, float y, float width, float height, int color, int max, int current)
{ {
super(x, y, width, height); super(x, y, width, height);
this.color = color; this.color = color;
this.max = max; this.max = max;
this.current = current; this.current = current;
} }
@Override @Override
public void init() public void init()
{ {
} }
public ScrollBarComponent setColor(int color) public ScrollBarComponent setColor(int color)
{ {
this.color = color; this.color = color;
return this; return this;
} }
public ScrollBarComponent setScrollMax(int max) public ScrollBarComponent setScrollMax(int max)
{ {
this.max = max; this.max = max;
return addScroll(0); return addScroll(0);
} }
public ScrollBarComponent addScroll(int add) public ScrollBarComponent addScroll(int add)
{ {
return setScrollCurrent(current + add); return setScrollCurrent(current + add);
} }
public ScrollBarComponent setScrollEnd() public ScrollBarComponent setScrollEnd()
{ {
return setScrollCurrent(max); return setScrollCurrent(max);
} }
public ScrollBarComponent setScrollStart() public ScrollBarComponent setScrollStart()
{ {
return setScrollCurrent(0); return setScrollCurrent(0);
} }
public ScrollBarComponent setScrollCurrent(int current) public ScrollBarComponent setScrollCurrent(int current)
{ {
this.current = (int)MathUtils.clamp(0F, Math.max(0, max - getBaseRange()), current); this.current = (int)MathUtils.clamp(0F, Math.max(0, max - getBaseRange()), current);
return this; return this;
} }
protected int getCurrent() protected int getCurrent()
{ {
return current; return current;
} }
protected void setCurrent(int value) protected void setCurrent(int value)
{ {
current = value; current = value;
} }
public ScrollBarComponent setHorizontal(boolean value) public ScrollBarComponent setHorizontal(boolean value)
{ {
setFlag(FLAG_HORIZONTAL, value); setFlag(FLAG_HORIZONTAL, value);
return this; return this;
} }
public ScrollBarComponent setInverted(boolean value) public ScrollBarComponent setInverted(boolean value)
{ {
setFlag(FLAG_INVERTED, value); setFlag(FLAG_INVERTED, value);
return this; return this;
} }
public boolean isHorizontal() public boolean isHorizontal()
{ {
return isFlagSet(FLAG_HORIZONTAL); return isFlagSet(FLAG_HORIZONTAL);
} }
public int getScroll() public int getScroll()
{ {
return current; return current;
} }
public boolean isAtEnd() public boolean isAtEnd()
{ {
return (max - getBaseRange()) <= current; return (max - getBaseRange()) <= current;
} }
public boolean isInUse() public boolean isInUse()
{ {
return (max - getBaseRange()) > 0F; return (max - getBaseRange()) > 0F;
} }
public float getRequiredSpace() public float getRequiredSpace()
{ {
return (max - getBaseRange()) > 0F ? (isHorizontal() ? getBox().getHeight() : getBox().getWidth()) : 0F; return (max - getBaseRange()) > 0F ? (isHorizontal() ? getBox().getHeight() : getBox().getWidth()) : 0F;
} }
@Override @Override
public boolean isComponentColliding(int mouseX, int mouseY) public boolean isComponentColliding(int mouseX, int mouseY)
{ {
return isInUse() && isHovered(mouseX, mouseY); return isInUse() && isHovered(mouseX, mouseY);
} }
@Override @Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks) public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{ {
float baseRange = getBaseRange(); float baseRange = getBaseRange();
float extra = max - baseRange; float extra = max - baseRange;
if(extra <= 0) if(extra <= 0)
{ {
return true; return true;
} }
IGuiBox box = getBox(); IGuiBox box = getBox();
float range = getRange(); float range = getRange();
float min = getCurrent() * (baseRange - range) / extra; float min = getCurrent() * (baseRange - range) / extra;
float brightness = getActiveBrightness(); float brightness = getActiveBrightness();
getRenderer().setBrightness(brightness * 0.5F).drawQuad(box, color); 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); 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); else getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(), box.getMinY(min), box.getMaxX(), box.getMinY(min + range), 0.01F, color);
getRenderer().setBrightness(1F); getRenderer().setBrightness(1F);
return true; return true;
} }
@Override @Override
public boolean onClick(int button, int mouseX, int mouseY) public boolean onClick(int button, int mouseX, int mouseY)
{ {
float baseRange = getBaseRange(); float baseRange = getBaseRange();
float extra = max - baseRange; float extra = max - baseRange;
if(extra <= 0F) if(extra <= 0F)
{ {
return false; return false;
} }
float range = getRange(); float range = getRange();
float pos = (baseRange - range) / extra; float pos = (baseRange - range) / extra;
float start = Math.max(0F, getCurrent() * pos); float start = Math.max(0F, getCurrent() * pos);
IGuiBox box = getBox(); IGuiBox box = getBox();
float currentPos = (isHorizontal() ? box.getMinX(start) : box.getMinY(start)) + ((range * box.getScale()) / 2F); float currentPos = (isHorizontal() ? box.getMinX(start) : box.getMinY(start)) + ((range * box.getScale()) / 2F);
float mouse = isHorizontal() ? mouseX : mouseY; float mouse = isHorizontal() ? mouseX : mouseY;
if(mouse < currentPos) if(mouse < currentPos)
{ {
setCurrent((int)Math.max(0F, getCurrent() - (((currentPos - mouse) / pos) / box.getScale()))); setCurrent((int)Math.max(0F, getCurrent() - (((currentPos - mouse) / pos) / box.getScale())));
} }
else if(mouse > currentPos) else if(mouse > currentPos)
{ {
setCurrent((int)Math.min(extra, getCurrent() + (((mouse - currentPos) / pos) / box.getScale()))); setCurrent((int)Math.min(extra, getCurrent() + (((mouse - currentPos) / pos) / box.getScale())));
} }
lastMouse = mouse; lastMouse = mouse;
return true; return true;
} }
@Override @Override
public boolean onDrag(int mouseX, int mouseY) public boolean onDrag(int mouseX, int mouseY)
{ {
if(lastMouse != -1F) if(lastMouse != -1F)
{ {
float range = getRange(); float range = getRange();
IGuiBox box = getBox(); IGuiBox box = getBox();
float mouse = (isHorizontal() ? mouseX - box.getMinX() : mouseY - box.getMinY()) - ((range * box.getScale()) / 2F); float mouse = (isHorizontal() ? mouseX - box.getMinX() : mouseY - box.getMinY()) - ((range * box.getScale()) / 2F);
float baseRange = getBaseRange(); float baseRange = getBaseRange();
float extra = max - baseRange; float extra = max - baseRange;
setCurrent((int)MathUtils.clamp(0F, Math.max(0F, extra), (mouse / ((baseRange - range) / extra)) / box.getScale())); setCurrent((int)MathUtils.clamp(0F, Math.max(0F, extra), (mouse / ((baseRange - range) / extra)) / box.getScale()));
return true; return true;
} }
return false; return false;
} }
@Override @Override
public void onRelease(int button, int mouseX, int mouseY) public void onRelease(int button, int mouseX, int mouseY)
{ {
lastMouse = -1F; lastMouse = -1F;
} }
@Override @Override
public boolean onScroll(int scroll, int mouseX, int mouseY) public boolean onScroll(int scroll, int mouseX, int mouseY)
{ {
float extra = max - getBaseRange(); float extra = max - getBaseRange();
if(extra > 0F) if(extra > 0F)
{ {
setCurrent((int)MathUtils.clamp(0, extra, current - (scroll * (extra / 10F)))); setCurrent((int)MathUtils.clamp(0, extra, current - (scroll * (extra / 10F))));
return true; return true;
} }
return false; return false;
} }
protected float getBaseRange() protected float getBaseRange()
{ {
return isHorizontal() ? getBox().getBaseWidth() : getBox().getBaseHeight(); return isHorizontal() ? getBox().getBaseWidth() : getBox().getBaseHeight();
} }
protected float getRange() protected float getRange()
{ {
float value = getBaseRange(); float value = getBaseRange();
return MathUtils.clamp(10F, value, ((value * value) / max)); return MathUtils.clamp(10F, value, ((value * value) / max));
} }
} }

View File

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

View File

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

View File

@ -1,363 +1,363 @@
package speiger.src.coreengine.rendering.gui.components; package speiger.src.coreengine.rendering.gui.components;
import java.util.Collection; import java.util.Collection;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import speiger.src.collections.ints.collections.IntCollection; import speiger.src.collections.ints.collections.IntCollection;
import speiger.src.coreengine.math.value.IValue; import speiger.src.coreengine.math.value.IValue;
import speiger.src.coreengine.math.value.LiniarValue; import speiger.src.coreengine.math.value.LiniarValue;
import speiger.src.coreengine.rendering.gui.GuiComponent; import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent; import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.components.list.SelectionEntry; import speiger.src.coreengine.rendering.gui.components.list.SelectionEntry;
import speiger.src.coreengine.rendering.gui.helper.Align; import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox; 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.Constrain.Target;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains; import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer; import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer; import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
import speiger.src.coreengine.rendering.tesselation.Tesselator; import speiger.src.coreengine.rendering.tesselation.Tesselator;
import speiger.src.coreengine.rendering.tesselation.VertexType; import speiger.src.coreengine.rendering.tesselation.VertexType;
public class SelectionComponent extends GuiComponent implements IButtonComponent, Consumer<GuiComponent> public class SelectionComponent extends GuiComponent implements IButtonComponent, Consumer<GuiComponent>
{ {
public static final int FLAG_ANIMATE = 1 << 20; public static final int FLAG_ANIMATE = 1 << 20;
ListComponent<SelectionEntry> list = new ListComponent<SelectionEntry>().bounds(0F, 120F).setManualRenderer(true).setIgnoreBounds(true).cast(); 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(); TextComponent text = new TextComponent().align(Align.LEFT_TOP, Align.CENTER).setTextScale(0.85F).setManualRenderer(true).cast();
RenderBuffer buffer; RenderBuffer buffer;
int color; int color;
boolean isOpen = false; boolean isOpen = false;
int selectedIndex = -1; int selectedIndex = -1;
int defaultIndex = -1; int defaultIndex = -1;
IValue animation = null; IValue animation = null;
public SelectionComponent(int color) public SelectionComponent(int color)
{ {
super(0F, 0F, 0F, 0F); super(0F, 0F, 0F, 0F);
this.color = color; this.color = color;
text.setText("Select Index"); text.setText("Select Index");
list.setColor(color); list.setColor(color);
} }
public SelectionComponent(int color, Collection<String> collection) public SelectionComponent(int color, Collection<String> collection)
{ {
super(0F, 0F, 0F, 0F); super(0F, 0F, 0F, 0F);
this.color = color; this.color = color;
text.setText("Select Index"); text.setText("Select Index");
list.setColor(color); list.setColor(color);
addEntries(collection); addEntries(collection);
} }
public SelectionComponent(float x, float y, float width, float height, int color) public SelectionComponent(float x, float y, float width, float height, int color)
{ {
super(x, y, width, height); super(x, y, width, height);
this.color = color; this.color = color;
text.setText("Select Index"); text.setText("Select Index");
list.setColor(color); list.setColor(color);
} }
public SelectionComponent(float x, float y, float width, float height, int color, Collection<String> collection) public SelectionComponent(float x, float y, float width, float height, int color, Collection<String> collection)
{ {
super(x, y, width, height); super(x, y, width, height);
this.color = color; this.color = color;
text.setText("Select Index"); text.setText("Select Index");
list.setColor(color); list.setColor(color);
addEntries(collection); addEntries(collection);
} }
@Override @Override
public void init() public void init()
{ {
list.setEntryHeight(getGui().getFont().height()).addUserActionListener(this); list.setEntryHeight(getGui().getFont().height()).onAction(this);
addChild(text, Constrains.parent(21F, 0F, 10.5F, 0F)); addChild(text, Constrains.parent(21F, 0F, 10.5F, 0F));
addChild(list, Constrains.parent(Target.X).invParent(Target.Y).parent(Target.WIDTH).build()); addChild(list, Constrains.parent(Target.X).invParent(Target.Y).parent(Target.WIDTH).build());
addCloseListener(buffer = getRenderer().createBuffer()); onClose(buffer = getRenderer().createBuffer());
createArrow(); createArrow();
} }
public final SelectionComponent setAnimating(boolean value) public final SelectionComponent setAnimating(boolean value)
{ {
setFlag(FLAG_ANIMATE, value); setFlag(FLAG_ANIMATE, value);
return this; return this;
} }
public final boolean isAnimating() public final boolean isAnimating()
{ {
return isFlagSet(FLAG_ANIMATE); return isFlagSet(FLAG_ANIMATE);
} }
@Override @Override
protected void updateState() protected void updateState()
{ {
list.setVisible(isOpen); list.setVisible(isOpen);
} }
public TextComponent getText() public TextComponent getText()
{ {
return text; return text;
} }
public ListComponent<SelectionEntry> getList() public ListComponent<SelectionEntry> getList()
{ {
return list; return list;
} }
public SelectionComponent addEntry(String s) public SelectionComponent addEntry(String s)
{ {
list.add(new SelectionEntry(s)); list.add(new SelectionEntry(s));
return this; return this;
} }
public SelectionComponent addEntries(Collection<String> collection) public SelectionComponent addEntries(Collection<String> collection)
{ {
for(String s : collection) for(String s : collection)
{ {
list.add(new SelectionEntry(s)); list.add(new SelectionEntry(s));
} }
return this; return this;
} }
public SelectionComponent updateEntry(int index, String newName) public SelectionComponent updateEntry(int index, String newName)
{ {
list.get(index).setText(newName); list.get(index).setText(newName);
if(index == selectedIndex) if(index == selectedIndex)
{ {
updateSelection(); updateSelection();
} }
return this; return this;
} }
public SelectionComponent removeEntry(String s) public SelectionComponent removeEntry(String s)
{ {
for(int i = 0,m=list.size();i<m;i++) for(int i = 0,m=list.size();i<m;i++)
{ {
if(list.get(i).getText().equals(s)) if(list.get(i).getText().equals(s))
{ {
list.remove(i); list.remove(i);
if(selectedIndex == i) if(selectedIndex == i)
{ {
updateSelection(); updateSelection();
} }
return this; return this;
} }
} }
return this; return this;
} }
public SelectionComponent removeIndex(int index) public SelectionComponent removeIndex(int index)
{ {
if(list.remove(index) != null && selectedIndex == index) if(list.remove(index) != null && selectedIndex == index)
{ {
updateSelection(); updateSelection();
} }
return this; return this;
} }
public SelectionComponent removeIndexes(IntCollection values) public SelectionComponent removeIndexes(IntCollection values)
{ {
if(list.removeAll(values) && values.contains(selectedIndex)) if(list.removeAll(values) && values.contains(selectedIndex))
{ {
updateSelection(); updateSelection();
} }
return this; return this;
} }
public SelectionComponent setDefaultIndex(int index) public SelectionComponent setDefaultIndex(int index)
{ {
defaultIndex = index; defaultIndex = index;
if(index != -1 && selectedIndex == -1) if(index != -1 && selectedIndex == -1)
{ {
list.setSelectedIndex(index); list.setSelectedIndex(index);
updateSelection(); updateSelection();
} }
return this; return this;
} }
public SelectionComponent setSelectedIndex(int index) public SelectionComponent setSelectedIndex(int index)
{ {
list.setSelectedIndex(index); list.setSelectedIndex(index);
updateSelection(); updateSelection();
return this; return this;
} }
public int getSelectedIndex() public int getSelectedIndex()
{ {
return selectedIndex; return selectedIndex;
} }
public String getSelectedValue() public String getSelectedValue()
{ {
return list.get(selectedIndex).getText(); return list.get(selectedIndex).getText();
} }
protected void createArrow() protected void createArrow()
{ {
if(buffer == null) if(buffer == null)
{ {
return; return;
} }
buffer.clear(); buffer.clear();
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI).setOffset(-6F, -6F, 0F); 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(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 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(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, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 12F, 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, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(6F, 12F, 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.pos(12F, 6F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.setOffset(0F, 0F, 0F); tes.setOffset(0F, 0F, 0F);
buffer.finishShape(0); buffer.finishShape(0);
} }
@Override @Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks) protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{ {
if(animation != null) if(animation != null)
{ {
animation.update(particalTicks); animation.update(particalTicks);
if(animation.isDone()) if(animation.isDone())
{ {
if(animation.get() < 1F) if(animation.get() < 1F)
{ {
isOpen = false; isOpen = false;
list.setVisible(false); list.setVisible(false);
} }
animation = null; animation = null;
} }
} }
return true; return true;
} }
@Override @Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks) protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{ {
float brightness = getActiveBrightness(); float brightness = getActiveBrightness();
IGuiBox box = getBox(); IGuiBox box = getBox();
float minX = box.getMinX(10F); float minX = box.getMinX(10F);
float minY = box.getMinY(10F); float minY = box.getMinY(10F);
float currentZ = getRenderer().getCurrentZ(); float currentZ = getRenderer().getCurrentZ();
float rotation = animation != null ? animation.get() : (isOpen ? 90 : 0); float rotation = animation != null ? animation.get() : (isOpen ? 90 : 0);
UIRenderer render = getRenderer(); UIRenderer render = getRenderer();
render.setBrightness(brightness).drawQuad(box, color); 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.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.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); 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); text.render(mouseX, mouseY, particalTicks);
if(animation != null) if(animation != null)
{ {
float progress = animation.get() / 90F; float progress = animation.get() / 90F;
box = list.getBox(); box = list.getBox();
enableScissors(box.getMinX(), box.getMinY(), box.getWidth(), box.getHeight() * progress); enableScissors(box.getMinX(), box.getMinY(), box.getWidth(), box.getHeight() * progress);
list.render(mouseX, mouseY, particalTicks); list.render(mouseX, mouseY, particalTicks);
disableScissors(); disableScissors();
} }
else if(isOpen) else if(isOpen)
{ {
list.render(mouseX, mouseY, particalTicks); list.render(mouseX, mouseY, particalTicks);
} }
return true; return true;
} }
@Override @Override
public boolean isComponentColliding(int mouseX, int mouseY) public boolean isComponentColliding(int mouseX, int mouseY)
{ {
return isMouseOver(mouseX, mouseY) || (isOpen && list.isComponentColliding(mouseX, mouseY)); return isMouseOver(mouseX, mouseY) || (isOpen && list.isComponentColliding(mouseX, mouseY));
} }
@Override @Override
public boolean isValidButton(int button) public boolean isValidButton(int button)
{ {
return button == 0 || button == 2; return button == 0 || button == 2;
} }
@Override @Override
public boolean onClick(int button, int mouseX, int mouseY) public boolean onClick(int button, int mouseX, int mouseY)
{ {
//TODO look how to move into OnRelease //TODO look how to move into OnRelease
if(isOpen && button == 0) if(isOpen && button == 0)
{ {
if(isMouseOver(mouseX, mouseY) && animation == null) if(isMouseOver(mouseX, mouseY) && animation == null)
{ {
close(); close();
} }
return animation == null && list.onClick(button, mouseX, mouseY); return animation == null && list.onClick(button, mouseX, mouseY);
} }
if(button == 2) if(button == 2)
{ {
list.setSelectedIndex(-1); list.setSelectedIndex(-1);
updateSelection(); updateSelection();
return true; return true;
} }
isOpen = true; isOpen = true;
list.setVisible(true); list.setVisible(true);
if(isAnimating()) if(isAnimating())
{ {
animation = new LiniarValue(2F, 0F, 90F).setSmooth(); animation = new LiniarValue(2F, 0F, 90F).setSmooth();
} }
return true; return true;
} }
@Override @Override
public boolean onDrag(int mouseX, int mouseY) public boolean onDrag(int mouseX, int mouseY)
{ {
return isOpen && animation == null && list.onDrag(mouseX, mouseY); return isOpen && animation == null && list.onDrag(mouseX, mouseY);
} }
@Override @Override
public void onRelease(int button, int mouseX, int mouseY) public void onRelease(int button, int mouseX, int mouseY)
{ {
if(isOpen && animation == null) if(isOpen && animation == null)
{ {
list.onRelease(button, mouseX, mouseY); list.onRelease(button, mouseX, mouseY);
} }
} }
@Override @Override
public boolean onScroll(int scroll, int mouseX, int mouseY) public boolean onScroll(int scroll, int mouseX, int mouseY)
{ {
return isOpen && animation == null && list.onScroll(scroll, mouseX, mouseY); return isOpen && animation == null && list.onScroll(scroll, mouseX, mouseY);
} }
protected void close() protected void close()
{ {
if(isAnimating()) if(isAnimating())
{ {
animation = new LiniarValue(2F, 90F, 0F).setSmooth(); animation = new LiniarValue(2F, 90F, 0F).setSmooth();
} }
else else
{ {
isOpen = false; isOpen = false;
list.setVisible(false); list.setVisible(false);
} }
} }
@Override @Override
public void accept(GuiComponent t) public void accept(GuiComponent t)
{ {
updateSelection(); updateSelection();
close(); close();
} }
protected void updateSelection() protected void updateSelection()
{ {
if(list.hasSelected()) if(list.hasSelected())
{ {
selectedIndex = list.getSelectedIndex(); selectedIndex = list.getSelectedIndex();
text.setText(list.get(selectedIndex).getText()); text.setText(list.get(selectedIndex).getText());
} }
else if(defaultIndex != -1) else if(defaultIndex != -1)
{ {
list.setSelectedIndex(defaultIndex); list.setSelectedIndex(defaultIndex);
selectedIndex = list.getSelectedIndex(); selectedIndex = list.getSelectedIndex();
text.setText(list.get(selectedIndex).getText()); text.setText(list.get(selectedIndex).getText());
} }
else else
{ {
selectedIndex = -1; selectedIndex = -1;
text.setText("Select Index"); 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; package speiger.src.coreengine.rendering.gui.components;
import java.util.function.IntFunction; import java.util.function.IntFunction;
import speiger.src.coreengine.math.MathUtils; import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.misc.Facing; import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.rendering.gui.GuiComponent; import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.base.IButtonComponent; import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
import speiger.src.coreengine.rendering.gui.helper.UIShapes; 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.Constrains;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer; import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
public class SliderComponent extends GuiComponent implements IButtonComponent public class SliderComponent extends GuiComponent implements IButtonComponent
{ {
TextComponent text = new TextComponent(); TextComponent text = new TextComponent();
protected int color; protected int color;
protected boolean vertical = false; protected boolean vertical = false;
protected int min; protected int min;
protected int max; protected int max;
protected int value; protected int value;
int scrollEffect; int scrollEffect;
IntFunction<String> textBuilder; IntFunction<String> textBuilder;
protected RenderBuffer buffer; protected RenderBuffer buffer;
public SliderComponent(int min, int max, int value, int color, IntFunction<String> textBuilder) public SliderComponent(int min, int max, int value, int color, IntFunction<String> textBuilder)
{ {
this(0F, 0F, 0F, 0F, min, max, value, color, textBuilder); this(0F, 0F, 0F, 0F, min, max, value, color, 1F, textBuilder);
} }
public SliderComponent(float x, float y, float width, float height, int min, int max, int value, int color, IntFunction<String> textBuilder) public SliderComponent(int min, int max, int value, int color, float textScale, IntFunction<String> textBuilder)
{ {
super(x, y, width, height); this(0F, 0F, 0F, 0F, min, max, value, color, textScale, textBuilder);
this.min = min; }
this.max = max;
this.value = MathUtils.clamp(min, max, value); public SliderComponent(float x, float y, float width, float height, int min, int max, int value, int color, IntFunction<String> textBuilder)
this.color = color; {
this.textBuilder = textBuilder; this(x, y, width, height, min, max, value, color, 1F, textBuilder);
updateText(false); }
}
public SliderComponent(float x, float y, float width, float height, int min, int max, int value, int color, float textScale, IntFunction<String> textBuilder)
@Override {
public void init() super(x, y, width, height);
{ this.min = min;
text.setTextScale(0.35F); this.max = max;
addChild(text, Constrains.parent()); this.value = MathUtils.clamp(min, max, value);
createArrow(); this.color = color;
} text.setTextScale(textScale);
this.textBuilder = textBuilder;
protected void createArrow() updateText(false);
{ }
if(getGui() == null)
{ @Override
return; public void init()
} {
if(buffer == null) text.setTextScale(0.35F);
{ addChild(text, Constrains.parent());
addCloseListener(buffer = getRenderer().createBuffer()); createArrow();
} }
buffer.clear();
UIShapes.createArrow(buffer, 12F, 12F, color, vertical ? Facing.EAST : Facing.SOUTH); protected void createArrow()
} {
if(getGui() == null)
public TextComponent getText() {
{ return;
return text; }
} if(buffer == null)
{
public SliderComponent updateText(boolean notifyListeners) onClose(buffer = getRenderer().createBuffer());
{ }
if(textBuilder != null) buffer.clear();
{ UIShapes.createArrow(buffer, 12F, 12F, color, vertical ? Facing.EAST : Facing.SOUTH);
text.setText(textBuilder.apply(value)); }
}
if(notifyListeners) public TextComponent getText()
{ {
notifyListeners(LISTENER_USER_ACTION); return text;
} }
return this;
} public SliderComponent updateText(boolean notifyListeners)
{
public SliderComponent setColor(int color) if(textBuilder != null)
{ {
if(this.color != color) text.setText(textBuilder.apply(value));
{ }
this.color = color; if(notifyListeners)
createArrow(); {
} notifyListeners(LISTENER_USER_ACTION);
return this; }
} return this;
}
public SliderComponent setValue(int value)
{ public SliderComponent setColor(int color)
int lastValue = this.value; {
this.value = MathUtils.clamp(min, max, value); if(this.color != color)
if(lastValue != value) {
{ this.color = color;
updateText(true); createArrow();
} }
return this; return this;
} }
public SliderComponent addValue(int value) public SliderComponent setValue(int value)
{ {
return setValue(this.value + value); int lastValue = this.value;
} this.value = MathUtils.clamp(min, max, value);
if(lastValue != value)
public SliderComponent setScrollEffect(int scrollEffect) {
{ updateText(true);
this.scrollEffect = scrollEffect; }
return this; return this;
} }
public SliderComponent setVertical(boolean vertical) public SliderComponent addValue(int value)
{ {
if(this.vertical != vertical) return setValue(this.value + value);
{ }
this.vertical = vertical;
createArrow(); public SliderComponent setScrollEffect(int scrollEffect)
} {
return this; this.scrollEffect = scrollEffect;
} return this;
}
public int getValue()
{ public SliderComponent setVertical(boolean vertical)
return value; {
} if(this.vertical != vertical)
{
public float getPercentalValue() this.vertical = vertical;
{ createArrow();
return ((float)(value - min) / (float)(max - min)); }
} return this;
}
@Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks) public int getValue()
{ {
float brightness = getActiveBrightness(); return value;
float minX = getBox().getMinX(5F); }
float minY = getBox().getMinY(2F);
float maxX = getBox().getMaxX(-5F); public float getPercentalValue()
float maxY = getBox().getMaxY(-2F); {
float scale = 0.6F * getBox().getScale(); return ((float)(value - min) / (float)(max - min));
if(vertical) }
{
float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxY(-3F) - getBox().getMinY(3F))) + getBox().getMinY(3F); @Override
float left = getBox().getMinX(2F); public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
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); float brightness = getActiveBrightness();
} float minX = getBox().getMinX(5F);
else float minY = getBox().getMinY(2F);
{ float maxX = getBox().getMaxX(-5F);
float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxX(-6F) - getBox().getMinX(6F))) + getBox().getMinX(6F); float maxY = getBox().getMaxY(-2F);
float top = getBox().getMinY(); float scale = 0.6F * getBox().getScale();
getRenderer().setBrightness(brightness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brightness * 0.7F).drawFrame(minX, minY, maxX, maxY, 0.001F, color); if(vertical)
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); {
} float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxY(-3F) - getBox().getMinY(3F))) + getBox().getMinY(3F);
getRenderer().setBrightness(getBrightness(mouseX, mouseY)); float left = getBox().getMinX(2F);
renderChildren(mouseX, mouseY, particalTicks); getRenderer().setBrightness(brightness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brightness * 0.7F).drawFrame(minX, minY, maxX, maxY, 0.001F, color);
getRenderer().setBrightness(1F); 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);
return false; }
} else
{
@Override float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxX(-6F) - getBox().getMinX(6F))) + getBox().getMinX(6F);
public boolean onClick(int button, int mouseX, int mouseY) 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);
updateScroll(mouseX, mouseY); 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);
return true; }
} getRenderer().setBrightness(getBrightness(mouseX, mouseY));
renderChildren(mouseX, mouseY, particalTicks);
@Override getRenderer().setBrightness(1F);
public boolean onDrag(int mouseX, int mouseY) return false;
{ }
updateScroll(mouseX, mouseY);
return true; @Override
} public boolean onClick(int button, int mouseX, int mouseY)
{
@Override updateScroll(mouseX, mouseY);
public boolean onScroll(int scroll, int mouseX, int mouseY) return true;
{ }
if(scrollEffect != 0)
{ @Override
int newValue = MathUtils.clamp(min, max, value + (scroll * scrollEffect)); public boolean onDrag(int mouseX, int mouseY)
if(newValue != value) {
{ updateScroll(mouseX, mouseY);
value = newValue; return true;
updateText(true); }
}
} @Override
return scrollEffect != 0; public boolean onScroll(int scroll, int mouseX, int mouseY)
} {
if(scrollEffect != 0)
public void updateScroll(int mouseX, int mouseY) {
{ int newValue = MathUtils.clamp(min, max, value + (scroll * scrollEffect));
float pos = vertical ? (mouseY - getBox().getMinY(2F)) / getBox().getHeight(-5F) : (mouseX - getBox().getMinX(5F)) / getBox().getWidth(-11F); if(newValue != value)
int newValue = min + (int)(MathUtils.clamp(0F, 1F, pos) * (max - min)); {
if(newValue != value) value = newValue;
{ updateText(true);
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; package speiger.src.coreengine.rendering.gui.components;
import speiger.src.coreengine.math.misc.ColorUtils; import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent; import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.Align; import speiger.src.coreengine.rendering.gui.helper.Align;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox; import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.renderer.FontRenderer; import speiger.src.coreengine.rendering.gui.renderer.FontRenderer;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer; import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
import speiger.src.coreengine.rendering.gui.renderer.lexer.TextMetadata; import speiger.src.coreengine.rendering.gui.renderer.lexer.TextMetadata;
public class TextComponent extends GuiComponent public class TextComponent extends GuiComponent
{ {
public static final int FLAG_STRIKE_THROUGH = 1 << 20; public static final int FLAG_STRIKE_THROUGH = 1 << 20;
public static final int FLAG_UNDERLINE = 1 << 21; public static final int FLAG_UNDERLINE = 1 << 21;
public static final int FLAG_BOLD = 1 << 22; public static final int FLAG_BOLD = 1 << 22;
public static final int FLAG_FORMATTING = 1 << 23; public static final int FLAG_FORMATTING = 1 << 23;
public static final int FLAG_FLIPPED = 1 << 24; public static final int FLAG_FLIPPED = 1 << 24;
public static final int FLAG_LIMITED_WIDTH = 1 << 25; public static final int FLAG_LIMITED_WIDTH = 1 << 25;
public static final int FLAG_LIMITED_HEIGHT = 1 << 26; public static final int FLAG_LIMITED_HEIGHT = 1 << 26;
public static final int FLAG_AUTO_SCALE = 1 << 27; public static final int FLAG_AUTO_SCALE = 1 << 27;
public static final int FLAG_SINGLE_LINE = 1 << 28; public static final int FLAG_SINGLE_LINE = 1 << 28;
FontRenderer font; FontRenderer font;
String text = ""; String text = "";
Align vertical = Align.CENTER; Align vertical = Align.CENTER;
Align horizontal = Align.CENTER; Align horizontal = Align.CENTER;
int textColor = ColorUtils.WHITE; int textColor = ColorUtils.WHITE;
Integer backGroundColor = null; Integer backGroundColor = null;
float italic = 0F; float italic = 0F;
float textScale = 1F; float textScale = 1F;
RenderBuffer buffer; RenderBuffer buffer;
float initialSize; float initialSize;
TextMetadata metadata = new TextMetadata(this); TextMetadata metadata = new TextMetadata(this);
public TextComponent() public TextComponent()
{ {
super(0F, 0F, 0F, 0F); super(0F, 0F, 0F, 0F);
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT); setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
} }
public TextComponent(String text) public TextComponent(String text)
{ {
this(0F, 0F, 0F, 0F, text); this(0F, 0F, 0F, 0F, text);
} }
public TextComponent(float x, float y, float width, float height) public TextComponent(float x, float y, float width, float height)
{ {
super(x, y, width, height); super(x, y, width, height);
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT); setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
} }
public TextComponent(float x, float y, float width, float height, String text) public TextComponent(float x, float y, float width, float height, String text)
{ {
super(x, y, width, height); super(x, y, width, height);
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT); setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
setText(text); setText(text);
} }
@Override @Override
public void init() public void init()
{ {
addCloseListener(buffer = getRenderer().createBuffer()); onClose(buffer = getRenderer().createBuffer());
if(font == null) if(font == null)
{ {
setFont(getGui().getFont()); setFont(getGui().getFont());
} }
initialSize = getBox().getWidth(); initialSize = getBox().getWidth();
} }
@Override @Override
public boolean renderSelf(int mouseX, int mouseY, float particalTicks) public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{ {
if(text.isEmpty()) if(text.isEmpty())
{ {
return true; return true;
} }
float minX = getBox().getMinX(); float minX = getBox().getMinX();
float minY = getBox().getMinY(); float minY = getBox().getMinY();
getRenderer().translate(minX, minY).setActiveTexture(font.getTexture()).drawBuffers(buffer, getBox().getWidth(), getBox().getHeight()).translate(-minX, -minY); getRenderer().translate(minX, minY).setActiveTexture(font.getTexture()).drawBuffers(buffer, getBox().getWidth(), getBox().getHeight()).translate(-minX, -minY);
return true; return true;
} }
@Override @Override
public void calculateActualBounds(float[] area, boolean start) public void calculateActualBounds(float[] area, boolean start)
{ {
if(start) if(start)
{ {
area[0] = Float.MAX_VALUE; area[0] = Float.MAX_VALUE;
area[1] = Float.MAX_VALUE; area[1] = Float.MAX_VALUE;
area[2] = Float.MIN_VALUE; area[2] = Float.MIN_VALUE;
area[3] = Float.MIN_VALUE; area[3] = Float.MIN_VALUE;
} }
IGuiBox box = getBox(); IGuiBox box = getBox();
area[0] = Math.min(area[0], box.getMinX() - metadata.getStartX()); area[0] = Math.min(area[0], box.getMinX() - metadata.getStartX());
area[1] = Math.min(area[1], box.getMinY() - metadata.getStartY()); area[1] = Math.min(area[1], box.getMinY() - metadata.getStartY());
area[2] = Math.max(area[2], (box.getMinX() - metadata.getStartX()) + metadata.getMaxWidth()); area[2] = Math.max(area[2], (box.getMinX() - metadata.getStartX()) + metadata.getMaxWidth());
area[3] = Math.max(area[3], (box.getMinY() - metadata.getStartY()) + metadata.getMaxHeight()); area[3] = Math.max(area[3], (box.getMinY() - metadata.getStartY()) + metadata.getMaxHeight());
for(GuiComponent comp : getChildren()) for(GuiComponent comp : getChildren())
{ {
if(comp.isVisible()) comp.calculateActualBounds(area, false); if(comp.isVisible()) comp.calculateActualBounds(area, false);
} }
} }
public RenderBuffer getBuffer() public RenderBuffer getBuffer()
{ {
return buffer; return buffer;
} }
@Override @Override
protected void repaint() protected void repaint()
{ {
metadata.clear(); metadata.clear();
if(font == null) if(font == null)
{ {
return; return;
} }
font.updateText(this); font.updateText(this);
} }
public TextComponent setTextScale(float textScale) public TextComponent setTextScale(float textScale)
{ {
if(this.textScale != textScale) if(this.textScale != textScale)
{ {
this.textScale = textScale; this.textScale = textScale;
onChanged(true); onChanged(true);
} }
return this; return this;
} }
public TextMetadata getMetadata() public TextMetadata getMetadata()
{ {
return metadata; return metadata;
} }
public final float getTextScale() public final float getTextScale()
{ {
return textScale * getBox().getScale() * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F); return textScale * getBox().getScale() * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F);
} }
public final float getRawTextScale() public final float getRawTextScale()
{ {
return textScale * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F); return textScale * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F);
} }
public final float getWidth() public final float getWidth()
{ {
return getBox().getWidth() / getTextScale(); return getBox().getWidth() / getTextScale();
} }
public final float getItalic() public final float getItalic()
{ {
return italic; return italic;
} }
public final boolean isBold() public final boolean isBold()
{ {
return isFlagSet(FLAG_BOLD); return isFlagSet(FLAG_BOLD);
} }
public final boolean isStrikeThrough() public final boolean isStrikeThrough()
{ {
return isFlagSet(FLAG_STRIKE_THROUGH); return isFlagSet(FLAG_STRIKE_THROUGH);
} }
public final boolean isUnderlined() public final boolean isUnderlined()
{ {
return isFlagSet(FLAG_UNDERLINE); return isFlagSet(FLAG_UNDERLINE);
} }
public final boolean isFlipped() public final boolean isFlipped()
{ {
return isFlagSet(FLAG_FLIPPED); return isFlagSet(FLAG_FLIPPED);
} }
public final boolean isRenderingSpecial() public final boolean isRenderingSpecial()
{ {
return isFlagSet(FLAG_FORMATTING); return isFlagSet(FLAG_FORMATTING);
} }
public final boolean isWidthLimited() public final boolean isWidthLimited()
{ {
return isFlagSet(FLAG_LIMITED_WIDTH); return isFlagSet(FLAG_LIMITED_WIDTH);
} }
public final boolean isHeightLimited() public final boolean isHeightLimited()
{ {
return isFlagSet(FLAG_LIMITED_HEIGHT); return isFlagSet(FLAG_LIMITED_HEIGHT);
} }
public final boolean isLimitedText() public final boolean isLimitedText()
{ {
return isFlagSet(FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT); return isFlagSet(FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
} }
public final boolean isAutoScaling() public final boolean isAutoScaling()
{ {
return isFlagSet(FLAG_AUTO_SCALE); return isFlagSet(FLAG_AUTO_SCALE);
} }
public final boolean isForcedSingleLine() public final boolean isForcedSingleLine()
{ {
return isFlagSet(FLAG_SINGLE_LINE); return isFlagSet(FLAG_SINGLE_LINE);
} }
public final int getTextColor() public final int getTextColor()
{ {
return textColor; return textColor;
} }
public final Integer getBackgroundColor() public final Integer getBackgroundColor()
{ {
return backGroundColor; return backGroundColor;
} }
@Override @Override
public FontRenderer getFont() public FontRenderer getFont()
{ {
return font; return font;
} }
public String getText() public String getText()
{ {
return text; return text;
} }
public String getText(int min) public String getText(int min)
{ {
return text.substring(min); return text.substring(min);
} }
public String getText(int min, int max) public String getText(int min, int max)
{ {
return text.substring(min, max); return text.substring(min, max);
} }
public int length() public int length()
{ {
return text.length(); return text.length();
} }
public Align getVertical() public Align getVertical()
{ {
return vertical; return vertical;
} }
public Align getHorizontal() public Align getHorizontal()
{ {
return horizontal; return horizontal;
} }
public final TextComponent bold(boolean value) public final TextComponent bold(boolean value)
{ {
if(setFlag(FLAG_BOLD, value)) if(setFlag(FLAG_BOLD, value))
{ {
return this; return this;
} }
onChanged(true); onChanged(true);
return this; return this;
} }
public final TextComponent strikethrough(boolean value) public final TextComponent strikethrough(boolean value)
{ {
if(!setFlag(FLAG_STRIKE_THROUGH, value)) if(!setFlag(FLAG_STRIKE_THROUGH, value))
{ {
return this; return this;
} }
onChanged(true); onChanged(true);
return this; return this;
} }
public final TextComponent underline(boolean value) public final TextComponent underline(boolean value)
{ {
if(!setFlag(FLAG_UNDERLINE, value)) if(!setFlag(FLAG_UNDERLINE, value))
{ {
return this; return this;
} }
onChanged(true); onChanged(true);
return this; return this;
} }
public final TextComponent flipped(boolean value) public final TextComponent flipped(boolean value)
{ {
if(!setFlag(FLAG_FLIPPED, value)) if(!setFlag(FLAG_FLIPPED, value))
{ {
return this; return this;
} }
onChanged(true); onChanged(true);
return this; return this;
} }
public final TextComponent special(boolean value) public final TextComponent special(boolean value)
{ {
if(!setFlag(FLAG_FORMATTING, value)) if(!setFlag(FLAG_FORMATTING, value))
{ {
return this; return this;
} }
onChanged(true); onChanged(true);
return this; return this;
} }
public final TextComponent limit(boolean value) public final TextComponent limit(boolean value)
{ {
if(!setFlag(FLAG_LIMITED_HEIGHT | FLAG_LIMITED_WIDTH, value)) if(!setFlag(FLAG_LIMITED_HEIGHT | FLAG_LIMITED_WIDTH, value))
{ {
return this; return this;
} }
onChanged(true); onChanged(true);
return this; return this;
} }
public final TextComponent limitWidth(boolean value) public final TextComponent limitWidth(boolean value)
{ {
if(!setFlag(FLAG_LIMITED_WIDTH, value)) if(!setFlag(FLAG_LIMITED_WIDTH, value))
{ {
return this; return this;
} }
onChanged(true); onChanged(true);
return this; return this;
} }
public final TextComponent limitHeight(boolean value) public final TextComponent limitHeight(boolean value)
{ {
if(!setFlag(FLAG_LIMITED_HEIGHT, value)) if(!setFlag(FLAG_LIMITED_HEIGHT, value))
{ {
return this; return this;
} }
onChanged(true); onChanged(true);
return this; return this;
} }
public final TextComponent autoScale(boolean value) public final TextComponent autoScale(boolean value)
{ {
if(!setFlag(FLAG_AUTO_SCALE, value)) if(!setFlag(FLAG_AUTO_SCALE, value))
{ {
return this; return this;
} }
onChanged(true); onChanged(true);
return this; return this;
} }
public final TextComponent singleLine(boolean value) public final TextComponent singleLine(boolean value)
{ {
if(!setFlag(FLAG_SINGLE_LINE, value)) if(!setFlag(FLAG_SINGLE_LINE, value))
{ {
return this; return this;
} }
onChanged(true); onChanged(true);
return this; return this;
} }
public final TextComponent italic(boolean value) public final TextComponent italic(boolean value)
{ {
return italic(value ? 3F : 0F); return italic(value ? 3F : 0F);
} }
public final TextComponent italic(float value) public final TextComponent italic(float value)
{ {
if(italic != value) if(italic != value)
{ {
italic = value; italic = value;
onChanged(true); onChanged(true);
} }
return this; return this;
} }
public TextComponent align(Align horizontal, Align vertical) public TextComponent align(Align horizontal, Align vertical)
{ {
if(this.horizontal != horizontal || this.vertical != vertical) if(this.horizontal != horizontal || this.vertical != vertical)
{ {
this.horizontal = horizontal; this.horizontal = horizontal;
this.vertical = vertical; this.vertical = vertical;
onChanged(true); onChanged(true);
} }
return this; return this;
} }
public TextComponent horizontal(Align horizontal) public TextComponent horizontal(Align horizontal)
{ {
if(this.horizontal != horizontal) if(this.horizontal != horizontal)
{ {
this.horizontal = horizontal; this.horizontal = horizontal;
onChanged(true); onChanged(true);
} }
return this; return this;
} }
public TextComponent vertical(Align vertical) public TextComponent vertical(Align vertical)
{ {
if(this.vertical != vertical) if(this.vertical != vertical)
{ {
this.vertical = vertical; this.vertical = vertical;
onChanged(true); onChanged(true);
} }
return this; return this;
} }
public TextComponent setText(String text) public TextComponent setText(String text)
{ {
if(text == null) text = "null"; if(text == null) text = "null";
if(!this.text.equals(text)) if(!this.text.equals(text))
{ {
this.text = text; this.text = text;
onChanged(true); onChanged(true);
} }
return this; return this;
} }
public TextComponent textColor(int color) public TextComponent textColor(int color)
{ {
if(textColor != color) if(textColor != color)
{ {
textColor = color; textColor = color;
onChanged(true); onChanged(true);
} }
return this; return this;
} }
public TextComponent backgroundColor(int color) public TextComponent backgroundColor(int color)
{ {
if(backGroundColor != color) if(backGroundColor != color)
{ {
backGroundColor = color; backGroundColor = color;
onChanged(true); onChanged(true);
} }
return this; return this;
} }
public TextComponent setFont(FontRenderer font) public TextComponent setFont(FontRenderer font)
{ {
if(this.font != font) if(this.font != font)
{ {
this.font = font; this.font = font;
onChanged(true); onChanged(true);
} }
return this; return this;
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,66 +1,66 @@
package speiger.src.coreengine.rendering.gui.components.window.misc; package speiger.src.coreengine.rendering.gui.components.window.misc;
import speiger.src.coreengine.math.misc.ColorUtils; import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.components.ButtonComponent; import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
import speiger.src.coreengine.rendering.gui.components.TextComponent; import speiger.src.coreengine.rendering.gui.components.TextComponent;
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent; import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
import speiger.src.coreengine.rendering.gui.components.WindowComponent; 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.ParentConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain; 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.RelativeConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain; import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
public class TextInputComponent extends WindowComponent public class TextInputComponent extends WindowComponent
{ {
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F); 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); 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 confirm = new ButtonComponent("Confirm", ColorUtils.DARK_GREEN);
ButtonComponent cancel = new ButtonComponent("Cancel", ColorUtils.RED); ButtonComponent cancel = new ButtonComponent("Cancel", ColorUtils.RED);
public TextInputComponent(float width, String name, String message) public TextInputComponent(float width, String name, String message)
{ {
this(0F, 0F, width, name, message); this(0F, 0F, width, name, message);
} }
public TextInputComponent(float x, float y, float width, String name, String message) public TextInputComponent(float x, float y, float width, String name, String message)
{ {
super(x, y, width, 35F, FIXED_SIZE_POPUP, name); super(x, y, width, 35F, FIXED_SIZE_POPUP, name);
this.message.setText(message); this.message.setText(message);
} }
public TextFieldComponent getInput() public TextFieldComponent getInput()
{ {
return input; return input;
} }
public String getText() public String getText()
{ {
return input.getText(); return input.getText();
} }
@Override @Override
public void init() public void init()
{ {
super.init(); super.init();
confirm.getText().setTextScale(0.5F); confirm.getText().setTextScale(0.5F);
cancel.getText().setTextScale(0.5F); cancel.getText().setTextScale(0.5F);
input.getRawText().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(confirm.onChange(minimizedListener).onAction(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(cancel.onChange(minimizedListener).onAction(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(message.onChange(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)); 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()); getBox().setHeight(45F + message.getMetadata().getMaxHeight());
} }
private void onListen() private void onListen()
{ {
notifyListeners(LISTENER_USER_ACTION); notifyListeners(LISTENER_USER_ACTION);
closeListener.accept(this); closeListener.accept(this);
} }
@Override @Override
public boolean isPopup() public boolean isPopup()
{ {
return true; return true;
} }
} }

View File

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

View File

@ -1,125 +1,131 @@
package speiger.src.coreengine.rendering.gui.helper.constrains; package speiger.src.coreengine.rendering.gui.helper.constrains;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
import speiger.src.coreengine.math.misc.Facing; import speiger.src.coreengine.math.misc.Facing;
import speiger.src.coreengine.rendering.gui.GuiComponent; import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target; import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
import speiger.src.coreengine.utils.functions.FloatSupplier; import speiger.src.coreengine.utils.functions.FloatSupplier;
public class Constrains public class Constrains
{ {
Constrain[] constrains = new Constrain[4]; Constrain[] constrains = new Constrain[4];
private Constrains(Constrain[] array) private Constrains(Constrain[] array)
{ {
System.arraycopy(array, 0, constrains, 0, 4); System.arraycopy(array, 0, constrains, 0, 4);
} }
public Constrains(Constrain xPos, Constrain yPos, Constrain width, Constrain height) public Constrains(Constrain xPos, Constrain yPos, Constrain width, Constrain height)
{ {
constrains[0] = xPos; constrains[0] = xPos;
constrains[1] = yPos; constrains[1] = yPos;
constrains[2] = width; constrains[2] = width;
constrains[3] = height; constrains[3] = height;
} }
public void setOwner(GuiComponent owner, GuiComponent parent) public void setOwner(GuiComponent owner, GuiComponent parent)
{ {
for(int i = 0;i<4;i++) { for(int i = 0;i<4;i++) {
if(constrains[i] != null) { if(constrains[i] != null) {
constrains[i].setComponents(owner, parent, Target.by(i)); constrains[i].setComponents(owner, parent, Target.by(i));
} }
} }
} }
public void onComponentChanged() public void onComponentChanged()
{ {
for(int i = 0;i<4;i++) { for(int i = 0;i<4;i++) {
if(constrains[i] != null) constrains[i].apply(); 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() { 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 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 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 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) { public static Constrains scrollBar(BooleanSupplier supply, boolean horizontal, float barSize) {
Constrain bounds = new ConditionalConstraint(supply, new ParentConstrain(), new ParentConstrain(barSize / 2F)); 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); 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 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) public static Constrains border(float size, Facing side, float offset)
{ {
switch(side) switch(side)
{ {
case NORTH: return new Constrains(new ParentConstrain(), new ParentConstrain(offset), new ParentConstrain(), new PixelConstrain(size)); 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 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 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()); case WEST: return new Constrains(new ParentConstrain(offset), new ParentConstrain(), new PixelConstrain(size), new ParentConstrain());
default: return null; default: return null;
} }
} }
public static ConstrainBuilder xPos(Constrain xPos) { return new ConstrainBuilder().set(xPos, Target.X); } public static ConstrainBuilder builder() { return new ConstrainBuilder(); };
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 xPos(Constrain xPos) { return new ConstrainBuilder().set(xPos, Target.X); }
public static ConstrainBuilder height(Constrain height) { return new ConstrainBuilder().set(height, Target.HEIGHT); } 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 xPos(float xPos) { return new ConstrainBuilder().set(new PixelConstrain(xPos), Target.X); } public static ConstrainBuilder height(Constrain height) { return new ConstrainBuilder().set(height, Target.HEIGHT); }
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 xPos(float xPos) { return new ConstrainBuilder().set(new PixelConstrain(xPos), Target.X); }
public static ConstrainBuilder height(float height) { return new ConstrainBuilder().set(new PixelConstrain(height), Target.HEIGHT); } 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 xPosR(float xPos) { return new ConstrainBuilder().set(new RelativeConstrain(xPos), Target.X); } public static ConstrainBuilder height(float height) { return new ConstrainBuilder().set(new PixelConstrain(height), Target.HEIGHT); }
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 xPosR(float xPos) { return new ConstrainBuilder().set(new RelativeConstrain(xPos), Target.X); }
public static ConstrainBuilder heightR(float height) { return new ConstrainBuilder().set(new RelativeConstrain(height), Target.HEIGHT); } 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 parent(Target target) { return new ConstrainBuilder().set(new ParentConstrain(), target); } public static ConstrainBuilder heightR(float height) { return new ConstrainBuilder().set(new RelativeConstrain(height), Target.HEIGHT); }
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 parent(Target target) { return new ConstrainBuilder().set(new ParentConstrain(), target); }
public static ConstrainBuilder invParent(float padding, Target target) { return new ConstrainBuilder().set(new ParentConstrain(padding).invert(), target); } public static ConstrainBuilder invParent(Target target) { return new ConstrainBuilder().set(new ParentConstrain().invert(), target); }
public static ConstrainBuilder center(Target target) { return new ConstrainBuilder().set(new CenterConstrain(), target); } public static ConstrainBuilder parent(float padding, Target target) { return new ConstrainBuilder().set(new ParentConstrain(padding), target); }
public static ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return new ConstrainBuilder().set(new DynamicConstrain(provider), 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 class ConstrainBuilder 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); }
Constrain[] constrains = new Constrain[4]; public static ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return new ConstrainBuilder().set(new DynamicConstrain(provider), target); }
public ConstrainBuilder set(Constrain value, Target target) { public static class ConstrainBuilder
constrains[target.ordinal()] = value; {
return this; Constrain[] constrains = new Constrain[4];
}
public ConstrainBuilder set(Constrain value, Target target) {
public ConstrainBuilder xPos(Constrain xPos) { return set(xPos, Target.X); } constrains[target.ordinal()] = value;
public ConstrainBuilder yPos(Constrain yPos) { return set(yPos, Target.Y); } return this;
public ConstrainBuilder width(Constrain width) { return set(width, Target.WIDTH); } }
public ConstrainBuilder height(Constrain height) { return set(height, Target.HEIGHT); }
public ConstrainBuilder xPos(Constrain xPos) { return set(xPos, Target.X); }
public ConstrainBuilder xPos(float xPos) { return set(new PixelConstrain(xPos), Target.X); } public ConstrainBuilder yPos(Constrain yPos) { return set(yPos, Target.Y); }
public ConstrainBuilder yPos(float yPos) { return set(new PixelConstrain(yPos), Target.Y); } public ConstrainBuilder width(Constrain width) { return set(width, Target.WIDTH); }
public ConstrainBuilder width(float width) { return set(new PixelConstrain(width), Target.WIDTH); } public ConstrainBuilder height(Constrain height) { return set(height, Target.HEIGHT); }
public ConstrainBuilder height(float height) { return set(new PixelConstrain(height), Target.HEIGHT); }
public ConstrainBuilder xPos(float xPos) { return set(new PixelConstrain(xPos), Target.X); }
public ConstrainBuilder xPosR(float xPos) { return set(new RelativeConstrain(xPos), Target.X); } public ConstrainBuilder yPos(float yPos) { return set(new PixelConstrain(yPos), Target.Y); }
public ConstrainBuilder yPosR(float yPos) { return set(new RelativeConstrain(yPos), Target.Y); } public ConstrainBuilder width(float width) { return set(new PixelConstrain(width), Target.WIDTH); }
public ConstrainBuilder widthR(float width) { return set(new RelativeConstrain(width), Target.WIDTH); } public ConstrainBuilder height(float height) { return set(new PixelConstrain(height), Target.HEIGHT); }
public ConstrainBuilder heightR(float height) { return set(new RelativeConstrain(height), Target.HEIGHT); }
public ConstrainBuilder xPosR(float xPos) { return set(new RelativeConstrain(xPos), Target.X); }
public ConstrainBuilder parent(Target target) { return set(new ParentConstrain(), target); } public ConstrainBuilder yPosR(float yPos) { return set(new RelativeConstrain(yPos), Target.Y); }
public ConstrainBuilder invParent(Target target) { return set(new ParentConstrain().invert(), target); } public ConstrainBuilder widthR(float width) { return set(new RelativeConstrain(width), Target.WIDTH); }
public ConstrainBuilder parent(float padding, Target target) { return set(new ParentConstrain(padding), target); } public ConstrainBuilder heightR(float height) { return set(new RelativeConstrain(height), Target.HEIGHT); }
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 parent(Target target) { return set(new ParentConstrain(), target); }
public ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return set(new DynamicConstrain(provider), 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 Constrains build() 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); }
return new Constrains(constrains); 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; package speiger.src.coreengine.rendering.gui.renderer.buffer;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList; import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.GuiComponent; import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.models.DrawCall; import speiger.src.coreengine.rendering.models.DrawCall;
import speiger.src.coreengine.rendering.tesselation.Tesselator; import speiger.src.coreengine.rendering.tesselation.Tesselator;
import speiger.src.coreengine.rendering.tesselation.VertexList; import speiger.src.coreengine.rendering.tesselation.VertexList;
import speiger.src.coreengine.utils.collections.iterators.IndexIterator; import speiger.src.coreengine.utils.collections.iterators.IndexIterator;
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper; import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
public class RenderBuffer implements Consumer<GuiComponent>, Iterable<DrawCall> public class RenderBuffer implements Consumer<GuiComponent>, Iterable<DrawCall>
{ {
List<DrawCall> drawCalls = new ObjectArrayList<DrawCall>(); List<DrawCall> drawCalls = new ObjectArrayList<>();
Tesselator tesselator; Tesselator tesselator;
public RenderBuffer(Tesselator tesselator) public RenderBuffer(Tesselator tesselator)
{ {
this.tesselator = tesselator; this.tesselator = tesselator;
} }
@Override @Override
public void accept(GuiComponent t) public void accept(GuiComponent t)
{ {
clear(); clear();
} }
public <T extends DrawCall> T get(int index, Class<T> clz) public <T extends DrawCall> T get(int index, Class<T> clz)
{ {
return (T)drawCalls.get(index); return (T)drawCalls.get(index);
} }
public void addDrawCall(DrawCall call) public void addDrawCall(DrawCall call)
{ {
drawCalls.add(call); drawCalls.add(call);
} }
public void clear() public void clear()
{ {
drawCalls.clear(); drawCalls.clear();
} }
public Tesselator start(int shape, VertexList format) public Tesselator start(int shape, VertexList format)
{ {
return tesselator.begin(shape, format); return tesselator.begin(shape, format);
} }
public void finishShape(int texture, Tesselator tesselator) public void finishShape(int texture, Tesselator tesselator)
{ {
if(!tesselator.isDrawing()) if(!tesselator.isDrawing())
{ {
throw new IllegalStateException("Tesselator wasnt filled"); throw new IllegalStateException("Tesselator wasnt filled");
} }
tesselator.finishData(); tesselator.finishData();
if(tesselator.getVertexCount() <= 0) if(tesselator.getVertexCount() <= 0)
{ {
return; return;
} }
drawCalls.add(tesselator.getDrawCall(texture)); drawCalls.add(tesselator.getDrawCall(texture));
} }
public void finishShape(int texture) public void finishShape(int texture)
{ {
finishShape(texture, tesselator); finishShape(texture, tesselator);
} }
@Override @Override
public Iterator<DrawCall> iterator() public Iterator<DrawCall> iterator()
{ {
return drawCalls.iterator(); return drawCalls.iterator();
} }
public Iterable<DrawCall> selectionIterator(int...indexes) public Iterable<DrawCall> selectionIterator(int...indexes)
{ {
return IterableWrapper.wrap(new IndexIterator<>(drawCalls, indexes)); return IterableWrapper.wrap(new IndexIterator<>(drawCalls, indexes));
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,131 +1,139 @@
package speiger.src.coreengine.rendering.utils; package speiger.src.coreengine.rendering.utils;
import java.nio.IntBuffer; import java.nio.IntBuffer;
import java.util.List; import java.util.List;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL31; import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL44; import org.lwjgl.opengl.GL44;
import speiger.src.collections.objects.lists.ObjectArrayList; import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.utils.states.BlendState; import speiger.src.coreengine.rendering.utils.states.BlendState;
import speiger.src.coreengine.rendering.utils.states.CullState; import speiger.src.coreengine.rendering.utils.states.CullState;
import speiger.src.coreengine.rendering.utils.states.GLProvoking; import speiger.src.coreengine.rendering.utils.states.GLProvoking;
import speiger.src.coreengine.rendering.utils.states.GLState; import speiger.src.coreengine.rendering.utils.states.GLState;
import speiger.src.coreengine.rendering.utils.states.GLWireFrame; import speiger.src.coreengine.rendering.utils.states.GLWireFrame;
import speiger.src.coreengine.rendering.utils.states.IGLState; import speiger.src.coreengine.rendering.utils.states.IGLState;
import speiger.src.coreengine.rendering.utils.states.LineSize; import speiger.src.coreengine.rendering.utils.states.LineSize;
import speiger.src.coreengine.rendering.utils.states.PointSize; import speiger.src.coreengine.rendering.utils.states.PointSize;
import speiger.src.coreengine.utils.counters.averager.Counter; import speiger.src.coreengine.utils.counters.averager.Counter;
public class GLUtils public class GLUtils
{ {
static final List<IGLState> ALL_STATES = new ObjectArrayList<>(); 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 MULTI_SAMPLING = addState(new GLState(GL13.GL_MULTISAMPLE, false));
public static final GLState WIRE_FRAME = addState(new GLWireFrame()); public static final GLState WIRE_FRAME = addState(new GLWireFrame());
public static final GLState PROVOKING_VERTEX = addState(new GLProvoking()); 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 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 CullState CULL_FACE = addState(new CullState(GL11.GL_BACK));
public static final BlendState BLEND = addState(new BlendState()); 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 GLState CLIP_PLANE0 = addState(new GLState(GL11.GL_CLIP_PLANE0, false));
public static final PointSize POINT_SIZE = addState(new PointSize()); public static final PointSize POINT_SIZE = addState(new PointSize());
public static final LineSize LINE_SIZE = addState(new LineSize()); public static final LineSize LINE_SIZE = addState(new LineSize());
public static final ScissorsManager TESTER = new ScissorsManager(100); public static final ScissorsManager TESTER = new ScissorsManager(100);
public static final Counter[] COUNTERS = Counter.createCounters(4); public static final Counter[] COUNTERS = Counter.createCounters(4);
public static final ViewPortStack VIEW_PORT = new ViewPortStack(); public static final ViewPortStack VIEW_PORT = new ViewPortStack();
public static <T extends IGLState> T addState(T state) public static <T extends IGLState> T addState(T state)
{ {
ALL_STATES.add(state); ALL_STATES.add(state);
return state; return state;
} }
public static void onFrameEnded() public static void reapplyState()
{ {
for(int i = 0,m=COUNTERS.length;i<m;i++) for(int i = 0;i<ALL_STATES.size();i++)
{ {
COUNTERS[i].onFinished(); ALL_STATES.get(i).reapply();
} }
for(int i = 0;i<ALL_STATES.size();i++) }
{
ALL_STATES.get(i).cleanup(); public static void onFrameEnded()
} {
} for(int i = 0,m=COUNTERS.length;i<m;i++)
{
public static void drawArrays(int mode, int count) COUNTERS[i].onFinished();
{ }
drawArrays(mode, 0, count); for(int i = 0;i<ALL_STATES.size();i++)
} {
ALL_STATES.get(i).cleanup();
public static void drawArrays(int mode, int first, int count) }
{ }
addVerties(mode, count);
GL11.glDrawArrays(mode, first, count); public static void drawArrays(int mode, int count)
} {
drawArrays(mode, 0, count);
public static void drawElements(int mode, int count, int type, long indices) }
{
addVerties(mode, count); public static void drawArrays(int mode, int first, int count)
GL11.glDrawElements(mode, count, type, indices); {
} addVerties(mode, count);
GL11.glDrawArrays(mode, first, count);
public static void drawElements(int mode, IntBuffer buffer) }
{
addVerties(mode, buffer.remaining()); public static void drawElements(int mode, int count, int type, long indices)
GL11.glDrawElements(mode, buffer); {
} addVerties(mode, count);
GL11.glDrawElements(mode, count, type, indices);
public static void drawArraysInstanced(int mode, int first, int count, int instanced) }
{
addVerties(mode, count * instanced); public static void drawElements(int mode, IntBuffer buffer)
GL31.glDrawArraysInstanced(mode, first, count, instanced); {
} addVerties(mode, buffer.remaining());
GL11.glDrawElements(mode, buffer);
public static void drawElementsInstanced(int mode, int count, int type, long indices, int instanced) }
{
addVerties(mode, count * instanced); public static void drawArraysInstanced(int mode, int first, int count, int instanced)
GL31.glDrawElementsInstanced(mode, count, type, indices, instanced); {
} addVerties(mode, count * instanced);
GL31.glDrawArraysInstanced(mode, first, count, instanced);
public static void drawElementsIndirect(int mode, int type, long pointer, int drawCount, int stride) }
{
addVerties(mode, drawAmount(pointer, drawCount)); public static void drawElementsInstanced(int mode, int count, int type, long indices, int instanced)
GL44.glMultiDrawElementsIndirect(mode, type, pointer, drawCount, stride); {
} addVerties(mode, count * instanced);
GL31.glDrawElementsInstanced(mode, count, type, indices, instanced);
static int drawAmount(long pointer, int amount) }
{
int total = 0; public static void drawElementsIndirect(int mode, int type, long pointer, int drawCount, int stride)
return total; {
} addVerties(mode, drawAmount(pointer, drawCount));
GL44.glMultiDrawElementsIndirect(mode, type, pointer, drawCount, stride);
static void addVerties(int mode, int count) }
{
COUNTERS[0].add(count); static int drawAmount(long pointer, int amount)
switch(mode) {
{ int total = 0;
case GL11.GL_POINTS: return total;
COUNTERS[1].add(count); }
break;
case GL11.GL_LINES: static void addVerties(int mode, int count)
COUNTERS[2].add(count / 2); {
break; COUNTERS[0].add(count);
case GL11.GL_LINE_LOOP: switch(mode)
COUNTERS[2].add((count + 2) / 2); {
break; case GL11.GL_POINTS:
case GL11.GL_LINE_STRIP: COUNTERS[1].add(count);
COUNTERS[2].add(count - 1); break;
break; case GL11.GL_LINES:
case GL11.GL_TRIANGLES: COUNTERS[2].add(count / 2);
COUNTERS[3].add(count / 3); break;
break; case GL11.GL_LINE_LOOP:
case GL11.GL_TRIANGLE_STRIP: COUNTERS[2].add((count + 2) / 2);
COUNTERS[3].add(count - 2); break;
break; case GL11.GL_LINE_STRIP:
case GL11.GL_TRIANGLE_FAN: COUNTERS[2].add(count - 1);
COUNTERS[3].add(count - 2); break;
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; package speiger.src.coreengine.rendering.utils;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt; import java.awt.image.DataBufferInt;
import java.io.File; import java.io.File;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Supplier; import java.util.function.Supplier;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import speiger.src.coreengine.rendering.input.window.IWindowListener; import speiger.src.coreengine.rendering.input.window.IWindowListener;
import speiger.src.coreengine.rendering.input.window.Window; import speiger.src.coreengine.rendering.input.window.Window;
import speiger.src.coreengine.utils.helpers.FileUtils; import speiger.src.coreengine.utils.helpers.FileUtils;
import speiger.src.coreengine.utils.io.GifWriter; import speiger.src.coreengine.utils.io.GifWriter;
public class ScreenshotHandler implements IWindowListener public class ScreenshotHandler implements IWindowListener
{ {
public static final DateTimeFormatter FILE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss"); public static final DateTimeFormatter FILE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss");
public static final DateTimeFormatter FOLDER_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM"); public static final DateTimeFormatter FOLDER_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM");
static final ThreadPoolExecutor FACTORY = (ThreadPoolExecutor)Executors.newFixedThreadPool(1); static final ThreadPoolExecutor FACTORY = (ThreadPoolExecutor)Executors.newFixedThreadPool(1);
File folder; File folder;
int width; int width;
int height; int height;
ByteBuffer buffer; ByteBuffer buffer;
GifRecorder recorder; GifRecorder recorder;
Supplier<BufferedImage> imageProvider = this::getData; Supplier<BufferedImage> imageProvider = this::getData;
public ScreenshotHandler(File helper) public ScreenshotHandler(File helper)
{ {
FACTORY.setKeepAliveTime(1, TimeUnit.SECONDS); FACTORY.setKeepAliveTime(1, TimeUnit.SECONDS);
FACTORY.allowCoreThreadTimeOut(true); FACTORY.allowCoreThreadTimeOut(true);
folder = new File(helper, "Screenshots"); folder = new File(helper, "Screenshots");
} }
@Override @Override
public void onWindowChanged(Window window) public void onWindowChanged(Window window)
{ {
width = window.getWidth(); width = window.getWidth();
height = window.getHeight(); height = window.getHeight();
if(buffer != null) if(buffer != null)
{ {
MemoryUtil.memFree(buffer); MemoryUtil.memFree(buffer);
buffer = null; buffer = null;
} }
buffer = MemoryUtil.memAlloc(width * height * 4); buffer = MemoryUtil.memAlloc(width * height * 4);
} }
public void screenShot() public void screenShot()
{ {
ZonedDateTime time = ZonedDateTime.now(); ZonedDateTime time = ZonedDateTime.now();
File subFolder = new File(folder, time.format(FOLDER_FORMAT)); File subFolder = new File(folder, time.format(FOLDER_FORMAT));
FileUtils.ensureFolder(subFolder); FileUtils.ensureFolder(subFolder);
try try
{ {
ImageIO.write(getScreenShot(), "png", new File(subFolder, "Screenshot_"+time.format(FILE_FORMAT)+".png")); ImageIO.write(getScreenShot(), "png", new File(subFolder, "Screenshot_"+time.format(FILE_FORMAT)+".png"));
} }
catch(Exception e) catch(Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
} }
public boolean isRecording() public boolean isRecording()
{ {
return recorder != null && !recorder.isFinished(); return recorder != null && !recorder.isFinished();
} }
public void toggleRecording() public void toggleRecording()
{ {
if(isRecording()) if(isRecording())
{ {
stopRecording(); stopRecording();
} }
else else
{ {
startRecording(); startRecording();
} }
} }
//Undefined time recording //Undefined time recording
public void startRecording() public void startRecording()
{ {
record("Capture_"+ZonedDateTime.now().format(FILE_FORMAT)+".gif", 15, Integer.MAX_VALUE); record("Capture_"+ZonedDateTime.now().format(FILE_FORMAT)+".gif", 15, Integer.MAX_VALUE);
} }
public void record(String fileName, int fps, int time) public void record(String fileName, int fps, int time)
{ {
if(recorder == null) if(recorder == null)
{ {
File subFolder = new File(folder, ZonedDateTime.now().format(FOLDER_FORMAT)); File subFolder = new File(folder, ZonedDateTime.now().format(FOLDER_FORMAT));
FileUtils.ensureFolder(subFolder); FileUtils.ensureFolder(subFolder);
recorder = new GifRecorder(new File(subFolder, fileName), fps, time); recorder = new GifRecorder(new File(subFolder, fileName), fps, time);
} }
} }
public void stopRecording() public void stopRecording()
{ {
if(recorder != null) if(recorder != null)
{ {
recorder.finishPic(); recorder.finishPic();
recorder = null; recorder = null;
} }
} }
public void update() public void update()
{ {
if(recorder != null) if(recorder != null)
{ {
recorder.tick(imageProvider); recorder.tick(imageProvider);
if(recorder.isFinished()) if(recorder.isFinished())
{ {
recorder.finishPic(); recorder.finishPic();
recorder = null; recorder = null;
} }
} }
} }
private BufferedImage getData() private BufferedImage getData()
{ {
buffer.clear(); buffer.clear();
GL11.glReadBuffer(GL11.GL_FRONT); GL11.glReadBuffer(GL11.GL_FRONT);
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer); GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData(); int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
for(int x = 0;x < width;x++) for(int x = 0;x < width;x++)
{ {
for(int y = 0;y < height;y++) for(int y = 0;y < height;y++)
{ {
int i = (x + (width * y)) * 4; int i = (x + (width * y)) * 4;
int r = buffer.get(i) & 0xFF; int r = buffer.get(i) & 0xFF;
int g = buffer.get(i + 1) & 0xFF; int g = buffer.get(i + 1) & 0xFF;
int b = buffer.get(i + 2) & 0xFF; int b = buffer.get(i + 2) & 0xFF;
data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b; data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b;
} }
} }
return image; return image;
} }
public BufferedImage getScreenShot() public BufferedImage getScreenShot()
{ {
buffer.clear(); buffer.clear();
GL11.glReadBuffer(GL11.GL_FRONT); GL11.glReadBuffer(GL11.GL_FRONT);
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer); GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData(); int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
for(int x = 0;x < width;x++) for(int x = 0;x < width;x++)
{ {
for(int y = 0;y < height;y++) for(int y = 0;y < height;y++)
{ {
int i = (x + (width * y)) * 4; int i = (x + (width * y)) * 4;
int r = buffer.get(i) & 0xFF; int r = buffer.get(i) & 0xFF;
int g = buffer.get(i + 1) & 0xFF; int g = buffer.get(i + 1) & 0xFF;
int b = buffer.get(i + 2) & 0xFF; int b = buffer.get(i + 2) & 0xFF;
data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b; data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b;
} }
} }
return image; return image;
} }
public void cleanup() public void cleanup()
{ {
if(buffer != null) if(buffer != null)
{ {
MemoryUtil.memFree(buffer); MemoryUtil.memFree(buffer);
buffer = null; buffer = null;
} }
} }
public static class GifRecorder public static class GifRecorder
{ {
GifWriter writer; GifWriter writer;
long timeBetweenFrames; long timeBetweenFrames;
long lastTime = -1L; long lastTime = -1L;
long freeTime; long freeTime;
int totalPics; int totalPics;
public GifRecorder(File file, int fps, int time) public GifRecorder(File file, int fps, int time)
{ {
int ms = 1000 / fps; int ms = 1000 / fps;
writer = GifWriter.create(file, BufferedImage.TYPE_INT_ARGB, ms); writer = GifWriter.create(file, BufferedImage.TYPE_INT_ARGB, ms);
timeBetweenFrames = ms * 1000000L; timeBetweenFrames = ms * 1000000L;
freeTime = ms * 1000000L; freeTime = ms * 1000000L;
totalPics = fps * time; totalPics = fps * time;
} }
public void tick(Supplier<BufferedImage> supply) public void tick(Supplier<BufferedImage> supply)
{ {
if(lastTime == -1L) if(lastTime == -1L)
{ {
totalPics--; totalPics--;
insert(supply.get()); insert(supply.get());
lastTime = System.nanoTime(); lastTime = System.nanoTime();
return; return;
} }
long time = System.nanoTime(); long time = System.nanoTime();
long happend = time - lastTime; long happend = time - lastTime;
lastTime = time; lastTime = time;
freeTime -= happend; freeTime -= happend;
if(freeTime <= 0) if(freeTime <= 0)
{ {
freeTime += timeBetweenFrames; freeTime += timeBetweenFrames;
insert(supply.get()); insert(supply.get());
totalPics--; totalPics--;
} }
} }
private void insert(final BufferedImage newBuffer) private void insert(final BufferedImage newBuffer)
{ {
FACTORY.execute(new Runnable(){ FACTORY.execute(new Runnable(){
BufferedImage buffer = newBuffer; BufferedImage buffer = newBuffer;
@Override @Override
public void run() public void run()
{ {
if(writer != null) if(writer != null)
{ {
writer.insertPicture(buffer); writer.insertPicture(buffer);
} }
} }
}); });
} }
public boolean isFinished() public boolean isFinished()
{ {
return totalPics <= 0; return totalPics <= 0;
} }
public void finishPic() public void finishPic()
{ {
FACTORY.execute(new Runnable(){ FACTORY.execute(new Runnable(){
@Override @Override
public void run() public void run()
{ {
writer.close(); writer.close();
writer = null; writer = null;
} }
}); });
} }
} }
} }

View File

@ -1,37 +1,44 @@
package speiger.src.coreengine.rendering.utils.states; package speiger.src.coreengine.rendering.utils.states;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
public class BlendState extends GLState public class BlendState extends GLState
{ {
int src; int src;
int func; int func;
public BlendState() public BlendState()
{ {
super(GL11.GL_BLEND, false); super(GL11.GL_BLEND, false);
} }
@Override @Override
public BlendState push(boolean newValue) public BlendState push(boolean newValue)
{ {
super.push(newValue); super.push(newValue);
return this; return this;
} }
public BlendState setFunction(int src, int func) public BlendState setFunction(int src, int func)
{ {
if(this.src != src && this.func != func) if(this.src != src && this.func != func)
{ {
this.src = src; this.src = src;
this.func = func; this.func = func;
GL11.glBlendFunc(src, func); GL11.glBlendFunc(src, func);
} }
return this; return this;
} }
public void setDefault() @Override
{ public void reapply()
setFunction(GL11.GL_ONE, GL11.GL_ONE); {
} 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; package speiger.src.coreengine.rendering.utils.states;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
public class CullState extends GLState public class CullState extends GLState
{ {
int type; int type;
public CullState(int defaultState) public CullState(int defaultState)
{ {
super(GL11.GL_CULL_FACE, false); super(GL11.GL_CULL_FACE, false);
type = defaultState; type = defaultState;
} }
@Override @Override
public CullState push(boolean newValue) public CullState push(boolean newValue)
{ {
super.push(newValue); super.push(newValue);
return this; return this;
} }
public void setCullType(int type) public void setCullType(int type)
{ {
if(this.type != type) if(this.type != type)
{ {
this.type = type; this.type = type;
if(lastState) if(lastState)
{ {
GL11.glCullFace(type); 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; package speiger.src.coreengine.rendering.utils.states;
import speiger.src.collections.floats.lists.FloatArrayList; import speiger.src.collections.floats.collections.FloatStack;
import speiger.src.collections.floats.lists.FloatList; import speiger.src.collections.floats.lists.FloatArrayList;
public abstract class FloatState implements IGLState public abstract class FloatState implements IGLState
{ {
protected final float defaultValue; protected final float defaultValue;
protected FloatList states = new FloatArrayList(); protected FloatStack states = new FloatArrayList();
public FloatState(float defaultValue) public FloatState(float defaultValue)
{ {
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
} }
public void push(float newValue) public void push(float newValue)
{ {
if((states.isEmpty() && equalsNot(newValue, defaultValue)) || (states.size() > 0 && equalsNot(states.getFloat(states.size()-1), newValue))) if((states.isEmpty() && equalsNot(newValue, defaultValue)) || (states.size() > 0 && equalsNot(states.top(), newValue)))
{ {
setValue(newValue); setValue(newValue);
} }
states.add(newValue); states.push(newValue);
} }
public void pop() public void pop()
{ {
if(states.isEmpty()) throw new IllegalStateException("State is already reset"); if(states.isEmpty()) throw new IllegalStateException("State is already reset");
if(states.size() == 1 && equalsNot(defaultValue, states.getFloat(0))) float prev = states.pop();
{ if(states.isEmpty() && equalsNot(defaultValue, prev)) setValue(defaultValue);
setValue(defaultValue); else if(!states.isEmpty() && equalsNot(states.top(), prev)) setValue(states.top());
} }
else if(states.size() > 1 && equalsNot(states.getFloat(states.size()-2), states.getFloat(states.size()-1)))
{ protected abstract void setValue(float value);
setValue(states.getFloat(states.size()-2));
} protected abstract String getName();
states.removeFloat(states.size()-1);
} protected boolean equalsNot(float key, float value)
{
protected abstract void setValue(float value); return Float.floatToIntBits(key) != Float.floatToIntBits(value);
}
protected abstract String getName();
@Override
protected boolean equalsNot(float key, float value) public void reapply()
{ {
return Float.floatToIntBits(key) != Float.floatToIntBits(value); if(states.isEmpty()) setValue(defaultValue);
} else setValue(states.top());
}
@Override
public void cleanup() @Override
{ public void cleanup()
if(states.size() > 1) {
{ if(states.size() > 1)
float value = states.getFloat(states.size()-1); {
states.clear(); float value = states.top();
states.add(value); states.clear();
} states.push(value);
} }
} }
}

View File

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

View File

@ -1,76 +1,80 @@
package speiger.src.coreengine.utils.collections.pools; package speiger.src.coreengine.utils.collections.pools;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import speiger.src.collections.objects.lists.ObjectArrayList; import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList; import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.coreengine.utils.functions.Functions; import speiger.src.coreengine.utils.functions.Functions;
public class ThreadPool<T> implements IPool<T> public class ThreadPool<T> implements IPool<T>
{ {
int cap; int cap;
ObjectList<T> stack; ObjectList<T> stack;
Supplier<T> creator; Supplier<T> creator;
Consumer<T> acceptor; Consumer<T> acceptor;
public ThreadPool(int size, Supplier<T> creator) public ThreadPool(int size, Supplier<T> creator)
{ {
this(size, creator, Functions.getVoidConsumer()); this(size, creator, Functions.getVoidConsumer());
} }
public ThreadPool(int size, Supplier<T> creator, Consumer<T> acceptor) public ThreadPool(int size, Supplier<T> creator, Consumer<T> acceptor)
{ {
cap = size; cap = size;
stack = new ObjectArrayList<T>(size); stack = new ObjectArrayList<T>(size);
this.creator = creator; this.creator = creator;
this.acceptor = acceptor; this.acceptor = acceptor;
} }
@Override @Override
public synchronized void accept(T t) public synchronized void accept(T t)
{ {
if(stack.size() < cap) if(stack.size() < cap)
{ {
stack.add(t); stack.add(t);
acceptor.accept(t); acceptor.accept(t);
} }
} }
@Override @Override
public synchronized void accept(T[] array) public synchronized void accept(T[] array)
{ {
stack.addAll(array, 0, Math.min(array.length, cap - stack.size())); int size = 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++])); 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)
{ @Override
Iterator<T> iter = array.iterator(); public synchronized void accept(Collection<T> array)
for(int i = 0,m=Math.min(array.size(), cap - stack.size());i<m && iter.hasNext();i++) {
{ int size = Math.min(array.size(), cap - stack.size());
T next = iter.next(); if(size <= 0) return;
stack.add(next); Iterator<T> iter = array.iterator();
acceptor.accept(next); for(int i = 0;i<size && iter.hasNext();i++)
} {
} T next = iter.next();
stack.add(next);
@Override acceptor.accept(next);
public synchronized T get() }
{ }
return stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1);
} @Override
public synchronized T get()
@Override {
public synchronized T[] get(T[] array) return stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1);
{ }
for(int i = 0,m=array.length;i<m;i++)
{ @Override
array[i] = stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1); public synchronized T[] get(T[] array)
} {
return 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; package speiger.src.coreengine.utils.profiler;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import speiger.src.collections.longs.queues.LongArrayFIFOQueue; import speiger.src.collections.longs.queues.LongArrayFIFOQueue;
import speiger.src.collections.longs.queues.LongPriorityQueue; import speiger.src.collections.longs.queues.LongPriorityQueue;
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue; import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
import speiger.src.collections.objects.queues.ObjectPriorityDequeue; import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
import speiger.src.coreengine.rendering.utils.GLStamper; import speiger.src.coreengine.rendering.utils.GLStamper;
import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp; import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp;
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry; import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
public class GPUProfilerEntry implements IProfilerEntry public class GPUProfilerEntry implements IProfilerEntry
{ {
String name; String name;
String pathName; String pathName;
IProfiler owner; IProfiler owner;
IProfilerEntry parent; IProfilerEntry parent;
List<IProfilerEntry> children = new ArrayList<IProfilerEntry>(); List<IProfilerEntry> children = new ArrayList<IProfilerEntry>();
int debth = 0; int debth = 0;
int totalTicks = 0; int totalTicks = 0;
long maxTime = Long.MIN_VALUE; long maxTime = Long.MIN_VALUE;
long minTime = Long.MAX_VALUE; long minTime = Long.MAX_VALUE;
long average = 0L; long average = 0L;
LongPriorityQueue entries = new LongArrayFIFOQueue(); LongPriorityQueue entries = new LongArrayFIFOQueue();
long startTime = 0L; long startTime = 0L;
long currentTime = 0L; long currentTime = 0L;
ObjectPriorityDequeue<GLStamp> stamps = new ObjectArrayFIFOQueue<GLStamp>(); ObjectPriorityDequeue<GLStamp> stamps = new ObjectArrayFIFOQueue<GLStamp>();
public GPUProfilerEntry(String name, IProfiler owner) public GPUProfilerEntry(String name, IProfiler owner)
{ {
this.name = name; this.name = name;
pathName = name; pathName = name;
this.owner = owner; this.owner = owner;
} }
public void addChild(GPUProfilerEntry child) public void addChild(GPUProfilerEntry child)
{ {
if(child != null) if(child != null)
{ {
children.add(child); children.add(child);
child.setParent(this); child.setParent(this);
} }
} }
private void setParent(GPUProfilerEntry parent) private void setParent(GPUProfilerEntry parent)
{ {
this.parent = parent; this.parent = parent;
debth = parent.debth + 1; debth = parent.debth + 1;
pathName = parent.pathName+"/"+name; pathName = parent.pathName+"/"+name;
} }
public void start() public void start()
{ {
stamps.enqueue(GLStamper.INSTANCE.createStamp(owner.getName()).start()); stamps.enqueue(GLStamper.INSTANCE.createStamp(owner.getName()).start());
} }
public void stop() public void stop()
{ {
stamps.last().stop(); stamps.last().stop();
} }
public void onFrameFinished(boolean end) public void onFrameFinished(boolean end)
{ {
while(!stamps.isEmpty() && stamps.first().isFinished()) while(!stamps.isEmpty() && stamps.first().isFinished())
{ {
GLStamp stamp = stamps.dequeue(); GLStamp stamp = stamps.dequeue();
currentTime += stamp.getResult(); currentTime += stamp.getResult();
stamp.release(); stamp.release();
} }
average += currentTime; average += currentTime;
entries.enqueue(currentTime); entries.enqueue(currentTime);
if(entries.size() > 20) if(entries.size() > 100)
{ {
average -= entries.dequeue(); average -= entries.dequeue();
} }
currentTime = average / entries.size(); currentTime = average / entries.size();
minTime = Math.min(minTime, currentTime); minTime = Math.min(minTime, currentTime);
maxTime = Math.max(maxTime, currentTime); maxTime = Math.max(maxTime, currentTime);
currentTime = 0; currentTime = 0;
if(end && totalTicks++ >= 10) if(end && totalTicks++ >= 10)
{ {
minTime = currentTime; minTime = currentTime;
maxTime = currentTime; maxTime = currentTime;
totalTicks = 0; totalTicks = 0;
} }
} }
@Override @Override
public String getName() public String getName()
{ {
return name; return name;
} }
@Override @Override
public String getPathName() public String getPathName()
{ {
return pathName; return pathName;
} }
@Override @Override
public int getDebth() public int getDebth()
{ {
return debth; return debth;
} }
@Override @Override
public IProfiler getOwner() public IProfiler getOwner()
{ {
return owner; return owner;
} }
@Override @Override
public IProfilerEntry getParent() public IProfilerEntry getParent()
{ {
return parent; return parent;
} }
@Override @Override
public int getChildCount() public int getChildCount()
{ {
return children.size(); return children.size();
} }
@Override @Override
public IProfilerEntry getChild(int index) public IProfilerEntry getChild(int index)
{ {
return children.get(index); return children.get(index);
} }
@Override @Override
public long getMinTime() public long getMinTime()
{ {
return minTime; return minTime;
} }
@Override @Override
public long getNanoTime() public long getNanoTime()
{ {
return entries.isEmpty() ? 0L : average / entries.size(); return entries.isEmpty() ? 0L : average / entries.size();
} }
@Override @Override
public long getMaxTime() public long getMaxTime()
{ {
return maxTime; return maxTime;
} }
} }

View File

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

View File

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

View File

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