Latest Sync
This commit is contained in:
parent
c95e7ce20d
commit
b42e680b8a
137
build.gradle
137
build.gradle
|
@ -1,70 +1,69 @@
|
|||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse'
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
options.compilerArgs << "-Xlint:deprecation"
|
||||
}
|
||||
|
||||
eclipse {
|
||||
classpath {
|
||||
downloadJavadoc = true
|
||||
downloadSources = true
|
||||
}
|
||||
}
|
||||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||
maven {
|
||||
url = "https://maven.speiger.com/repository/main"
|
||||
}
|
||||
}
|
||||
|
||||
task srcJar(type: Jar) {
|
||||
from sourceSets.main.allSource
|
||||
classifier = 'sources'
|
||||
from {
|
||||
configurations.compile.collect {
|
||||
it.isDirectory() ? it : zipTree(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives srcJar
|
||||
}
|
||||
|
||||
jar{
|
||||
from {
|
||||
configurations.compile.collect {
|
||||
it.isDirectory() ? it : zipTree(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//LWJGL 3
|
||||
compile platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
|
||||
|
||||
compile "org.lwjgl:lwjgl"
|
||||
compile "org.lwjgl:lwjgl-glfw"
|
||||
compile "org.lwjgl:lwjgl-jemalloc"
|
||||
compile "org.lwjgl:lwjgl-openal"
|
||||
compile "org.lwjgl:lwjgl-opengl"
|
||||
compile "org.lwjgl:lwjgl-stb"
|
||||
compile "org.lwjgl:lwjgl-nfd"
|
||||
compile "org.lwjgl:lwjgl::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-glfw::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-jemalloc::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-openal::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-opengl::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-stb::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-nfd::$lwjglNatives"
|
||||
|
||||
//Gson
|
||||
compile 'com.google.code.gson:gson:2.8.6'
|
||||
|
||||
//Primitive Collections
|
||||
compile 'de.speiger:Primitive-Collections:0.6.1'
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse'
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
eclipse {
|
||||
classpath {
|
||||
downloadJavadoc = true
|
||||
downloadSources = true
|
||||
}
|
||||
}
|
||||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||
maven {
|
||||
url = "https://maven.speiger.com/repository/main"
|
||||
}
|
||||
}
|
||||
|
||||
task srcJar(type: Jar) {
|
||||
from sourceSets.main.allSource
|
||||
classifier = 'sources'
|
||||
from {
|
||||
configurations.compile.collect {
|
||||
it.isDirectory() ? it : zipTree(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives srcJar
|
||||
}
|
||||
|
||||
jar{
|
||||
from {
|
||||
configurations.compile.collect {
|
||||
it.isDirectory() ? it : zipTree(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//LWJGL 3
|
||||
compile platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
|
||||
|
||||
compile "org.lwjgl:lwjgl"
|
||||
compile "org.lwjgl:lwjgl-glfw"
|
||||
compile "org.lwjgl:lwjgl-jemalloc"
|
||||
compile "org.lwjgl:lwjgl-openal"
|
||||
compile "org.lwjgl:lwjgl-opengl"
|
||||
compile "org.lwjgl:lwjgl-stb"
|
||||
compile "org.lwjgl:lwjgl-nfd"
|
||||
compile "org.lwjgl:lwjgl::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-glfw::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-jemalloc::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-openal::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-opengl::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-stb::$lwjglNatives"
|
||||
compile "org.lwjgl:lwjgl-nfd::$lwjglNatives"
|
||||
|
||||
//Gson
|
||||
compile 'com.google.code.gson:gson:2.8.6'
|
||||
|
||||
//Primitive Collections
|
||||
compile 'de.speiger:Primitive-Collections:0.7.0'
|
||||
}
|
|
@ -1,143 +1,143 @@
|
|||
package speiger.src.coreengine.application;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
|
||||
import speiger.src.collections.objects.queues.ObjectPriorityQueue;
|
||||
import speiger.src.coreengine.rendering.input.window.Window;
|
||||
import speiger.src.coreengine.rendering.utils.AllocationTracker;
|
||||
import speiger.src.coreengine.rendering.utils.GLStamper;
|
||||
import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp;
|
||||
import speiger.src.coreengine.rendering.utils.GLUtils;
|
||||
import speiger.src.coreengine.utils.counters.averager.TimeAverager;
|
||||
import speiger.src.coreengine.utils.counters.timers.FPSTimer;
|
||||
import speiger.src.coreengine.utils.counters.timers.FrameSyncer;
|
||||
import speiger.src.coreengine.utils.counters.timers.TimerTarget;
|
||||
import speiger.src.coreengine.utils.helpers.FileUtils;
|
||||
import speiger.src.coreengine.utils.helpers.TextUtil;
|
||||
import speiger.src.coreengine.utils.io.GameLog;
|
||||
import speiger.src.coreengine.utils.io.GameLog.LogLevel;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler;
|
||||
|
||||
public class ApplicationExecutor
|
||||
{
|
||||
public static final DecimalFormat FORMATTER = new DecimalFormat("###");
|
||||
FPSTimer timer = new FPSTimer();
|
||||
TimerTarget fps = timer.getFPS();
|
||||
TimerTarget ups = timer.getUPS();
|
||||
FrameSyncer sync = new FrameSyncer();
|
||||
|
||||
TimeAverager gpuTime = new TimeAverager();
|
||||
ObjectPriorityQueue<GLStamp> stamps = new ObjectArrayFIFOQueue<>();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
long frame = 0L;
|
||||
|
||||
Application owner;
|
||||
|
||||
public ApplicationExecutor(Application owner)
|
||||
{
|
||||
this.owner = owner;
|
||||
owner.timer = timer;
|
||||
}
|
||||
|
||||
private IProfiler gpu()
|
||||
{
|
||||
return owner.gpuProfiler;
|
||||
}
|
||||
|
||||
public void start(Window window)
|
||||
{
|
||||
createTimeHacker();
|
||||
timer.init();
|
||||
try
|
||||
{
|
||||
while(window.shouldRun()) loop(window);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
GameLog.error("Client Has Crashed", e, LogLevel.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
private void loop(Window window)
|
||||
{
|
||||
GLStamp stamp = GLStamper.INSTANCE.createStamp("MainStamp").start();
|
||||
stamps.enqueue(stamp);
|
||||
gpu().start("Client").start("Update");
|
||||
window.update();
|
||||
for(long f = timer.getDelta();f >= ups.getTargetNS();f = timer.consumeDelta())
|
||||
{
|
||||
ups.tick();
|
||||
owner.updateInternal();
|
||||
builder.setLength(0);
|
||||
builder.append(owner.getMainWindowName());
|
||||
if(owner.showProfilingInfo) addDebugInfo(builder);
|
||||
window.setTitle(builder.toString());
|
||||
}
|
||||
gpu().next("Render");
|
||||
render(timer.getParticalTime());
|
||||
gpu().next("Trackers");
|
||||
boolean end = timer.update();
|
||||
stamp.stop();
|
||||
AllocationTracker.INSTANCE.update();
|
||||
GLUtils.onFrameEnded();
|
||||
gpu().next("Window").start("V-Sync");
|
||||
window.finishFrame();
|
||||
if(window.isCPULimited()) sync.sync(fps.getTargetTicks());
|
||||
gpu().next("Input");
|
||||
window.gatherInputs();
|
||||
gpu().stop().stop().stop().onFrameEnded(end);
|
||||
while(!stamps.isEmpty() && stamps.first().isFinished())
|
||||
{
|
||||
stamp = stamps.dequeue();
|
||||
gpuTime.addEntry(stamp.getResult());
|
||||
stamp.release();
|
||||
}
|
||||
frame++;
|
||||
}
|
||||
|
||||
private void render(float particalTicks)
|
||||
{
|
||||
gpu().start("Prep");
|
||||
fps.tick();
|
||||
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
|
||||
gpu().stop();
|
||||
owner.renderInternal(particalTicks);
|
||||
}
|
||||
|
||||
public void createTimeHacker()
|
||||
{
|
||||
Thread thread = new Thread(() -> {
|
||||
while (true){
|
||||
try {Thread.sleep(2147483647L);}
|
||||
catch (InterruptedException e){}
|
||||
}
|
||||
}, "Time Fixer Thread");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
protected void addDebugInfo(StringBuilder builder)
|
||||
{
|
||||
builder.append("(");
|
||||
builder.append(fps.getTicks()).append(":").append(ups.getTicks());
|
||||
owner.addExtraTickRates(T -> builder.append(":").append(T));
|
||||
builder.append(",").append(getMemoryUsage());
|
||||
builder.append(",").append("CPU-A: "+FileUtils.convertBytes(AllocationTracker.INSTANCE.getCPUAllocatedBytes()));
|
||||
builder.append(",").append("GPU-A: "+FileUtils.convertBytes(AllocationTracker.INSTANCE.getGPUAllocatedBytes()));
|
||||
builder.append(",").append(TextUtil.convertTime(timer.getUsage(), "Client:", FORMATTER));
|
||||
builder.append(",").append(TextUtil.convertTime(gpuTime.getAverage(), "GPU:", FORMATTER));
|
||||
owner.addExtraTimers((N, T) -> builder.append(",").append(TextUtil.convertTime(T, N, FORMATTER)));
|
||||
builder.append(")");
|
||||
}
|
||||
|
||||
private String getMemoryUsage()
|
||||
{
|
||||
Runtime time = Runtime.getRuntime();
|
||||
long aviable = time.totalMemory();
|
||||
return "Memory:"+((aviable - time.freeMemory()) >> 20)+"MB/"+(aviable >> 20)+"MB";
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.application;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
|
||||
import speiger.src.collections.objects.queues.ObjectPriorityQueue;
|
||||
import speiger.src.coreengine.rendering.input.window.Window;
|
||||
import speiger.src.coreengine.rendering.utils.AllocationTracker;
|
||||
import speiger.src.coreengine.rendering.utils.GLStamper;
|
||||
import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp;
|
||||
import speiger.src.coreengine.rendering.utils.GLUtils;
|
||||
import speiger.src.coreengine.utils.counters.averager.TimeAverager;
|
||||
import speiger.src.coreengine.utils.counters.timers.FPSTimer;
|
||||
import speiger.src.coreengine.utils.counters.timers.FrameSyncer;
|
||||
import speiger.src.coreengine.utils.counters.timers.TimerTarget;
|
||||
import speiger.src.coreengine.utils.helpers.FileUtils;
|
||||
import speiger.src.coreengine.utils.helpers.TextUtil;
|
||||
import speiger.src.coreengine.utils.io.GameLog;
|
||||
import speiger.src.coreengine.utils.io.GameLog.LogLevel;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler;
|
||||
|
||||
public class ApplicationExecutor
|
||||
{
|
||||
public static final DecimalFormat FORMATTER = new DecimalFormat("###");
|
||||
FPSTimer timer = new FPSTimer();
|
||||
TimerTarget fps = timer.getFPS();
|
||||
TimerTarget ups = timer.getUPS();
|
||||
FrameSyncer sync = new FrameSyncer();
|
||||
|
||||
TimeAverager gpuTime = new TimeAverager();
|
||||
ObjectPriorityQueue<GLStamp> stamps = new ObjectArrayFIFOQueue<>();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
long frame = 0L;
|
||||
|
||||
Application owner;
|
||||
|
||||
public ApplicationExecutor(Application owner)
|
||||
{
|
||||
this.owner = owner;
|
||||
owner.timer = timer;
|
||||
}
|
||||
|
||||
private IProfiler gpu()
|
||||
{
|
||||
return owner.gpuProfiler;
|
||||
}
|
||||
|
||||
public void start(Window window)
|
||||
{
|
||||
createTimeHacker();
|
||||
timer.init();
|
||||
try
|
||||
{
|
||||
while(window.shouldRun()) loop(window);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
GameLog.error("Client Has Crashed", e, LogLevel.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
private void loop(Window window)
|
||||
{
|
||||
GLStamp stamp = GLStamper.INSTANCE.createStamp("MainStamp").start();
|
||||
stamps.enqueue(stamp);
|
||||
gpu().start("Client").start("Update");
|
||||
window.update();
|
||||
for(long f = timer.getDelta();f >= ups.getTargetNS();f = timer.consumeDelta())
|
||||
{
|
||||
ups.tick();
|
||||
owner.updateInternal();
|
||||
builder.setLength(0);
|
||||
builder.append(owner.getMainWindowName());
|
||||
if(owner.showProfilingInfo) addDebugInfo(builder);
|
||||
window.setTitle(builder.toString());
|
||||
}
|
||||
gpu().next("Render");
|
||||
render(timer.getParticalTime());
|
||||
gpu().next("Trackers");
|
||||
boolean end = timer.update();
|
||||
stamp.stop();
|
||||
AllocationTracker.INSTANCE.update();
|
||||
GLUtils.onFrameEnded();
|
||||
gpu().next("Window").start("V-Sync");
|
||||
window.finishFrame();
|
||||
if(window.isCPULimited()) sync.sync(fps.getTargetTicks());
|
||||
gpu().next("Input");
|
||||
window.gatherInputs();
|
||||
gpu().stop().stop().stop().onFrameEnded(end);
|
||||
while(!stamps.isEmpty() && stamps.first().isFinished())
|
||||
{
|
||||
stamp = stamps.dequeue();
|
||||
gpuTime.addEntry(stamp.getResult());
|
||||
stamp.release();
|
||||
}
|
||||
frame++;
|
||||
}
|
||||
|
||||
private void render(float particalTicks)
|
||||
{
|
||||
gpu().start("Prep");
|
||||
fps.tick();
|
||||
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
|
||||
gpu().stop();
|
||||
owner.renderInternal(particalTicks);
|
||||
}
|
||||
|
||||
public void createTimeHacker()
|
||||
{
|
||||
Thread thread = new Thread(() -> {
|
||||
while (true){
|
||||
try {Thread.sleep(2147483647L);}
|
||||
catch (InterruptedException e){}
|
||||
}
|
||||
}, "Time Fixer Thread");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
protected void addDebugInfo(StringBuilder builder)
|
||||
{
|
||||
builder.append("(");
|
||||
builder.append(fps.getTicks()).append(":").append(ups.getTicks());
|
||||
owner.addExtraTickRates(T -> builder.append(":").append(T));
|
||||
builder.append(",").append(getMemoryUsage());
|
||||
builder.append(",").append("CPU-A: "+FileUtils.convertBytes(AllocationTracker.INSTANCE.getCPUAllocatedBytes()));
|
||||
builder.append(",").append("GPU-A: "+FileUtils.convertBytes(AllocationTracker.INSTANCE.getGPUAllocatedBytes()));
|
||||
builder.append(",").append(TextUtil.convertTime(timer.getUsage(), "Client:", FORMATTER));
|
||||
builder.append(",").append(TextUtil.convertTime(gpuTime.getAverage(), "GPU:", FORMATTER));
|
||||
owner.addExtraTimers((N, T) -> builder.append(",").append(TextUtil.convertTime(T, N, FORMATTER)));
|
||||
builder.append(")");
|
||||
}
|
||||
|
||||
private String getMemoryUsage()
|
||||
{
|
||||
Runtime time = Runtime.getRuntime();
|
||||
long aviable = time.totalMemory();
|
||||
return "Memory:"+((aviable - time.freeMemory()) >> 20)+"MB/"+(aviable >> 20)+"MB";
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,278 +1,278 @@
|
|||
package speiger.src.coreengine.rendering.gui;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import speiger.src.coreengine.assets.AssetLocation;
|
||||
import speiger.src.coreengine.math.vector.ints.Vec2i;
|
||||
import speiger.src.coreengine.rendering.gui.base.DebugOverlay;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.FontRenderer;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.GuiShader;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.provider.FontManager;
|
||||
import speiger.src.coreengine.rendering.input.events.KeyEvent.CharTypeEvent;
|
||||
import speiger.src.coreengine.rendering.input.events.KeyEvent.KeyPressEvent;
|
||||
import speiger.src.coreengine.rendering.input.events.MouseEvent;
|
||||
import speiger.src.coreengine.rendering.input.window.IWindowListener;
|
||||
import speiger.src.coreengine.rendering.input.window.ScaledResolution;
|
||||
import speiger.src.coreengine.rendering.input.window.Window;
|
||||
import speiger.src.coreengine.rendering.models.UniformBuffer;
|
||||
import speiger.src.coreengine.rendering.shader.ShaderTracker;
|
||||
import speiger.src.coreengine.rendering.utils.Cursor;
|
||||
import speiger.src.coreengine.rendering.utils.GLUtils;
|
||||
import speiger.src.coreengine.utils.eventbus.EventBus;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler;
|
||||
|
||||
public abstract class GuiManager implements IWindowListener
|
||||
{
|
||||
protected GuiBase[] activeGuis = new GuiBase[2];
|
||||
protected GuiBase gui;
|
||||
protected DebugOverlay debug;
|
||||
protected UIRenderer renderer = new UIRenderer(this);
|
||||
protected Window window;
|
||||
protected ScaledResolution res;
|
||||
protected long globalClock = 0L;
|
||||
protected boolean isReloading = false;
|
||||
protected FontRenderer font;
|
||||
protected GuiShader shader = ShaderTracker.INSTANCE.register(GuiShader::create, T -> shader = T);
|
||||
|
||||
public GuiManager(Window window, EventBus bus, FontManager manager)
|
||||
{
|
||||
this.window = window;
|
||||
font = manager.loadFont(AssetLocation.of("font/roboto.json"), 18.5F);
|
||||
bus.register(MouseEvent.class, this::onMouseEvent);
|
||||
bus.register(KeyPressEvent.class, (T) -> T.setCanceled(onKeyPressed(T.key)));
|
||||
bus.register(CharTypeEvent.class, (T) -> T.setCanceled(onCharTyped(T.character, T.codePoint)));
|
||||
window.addListener(this, false);
|
||||
debug = createOverlay();
|
||||
activeGuis[1] = debug;
|
||||
res = window.getUIFrame();
|
||||
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
debug.onInit();
|
||||
}
|
||||
|
||||
public abstract IProfiler getGPUProfiler();
|
||||
public abstract IProfiler getCPUProfiler();
|
||||
public abstract IProfiler getServerProfiler();
|
||||
public abstract UniformBuffer getOrthoMatrixBuffer();
|
||||
public abstract DebugOverlay createOverlay();
|
||||
|
||||
public void showGui(GuiBase base, boolean allowBack)
|
||||
{
|
||||
if(allowBack)
|
||||
{
|
||||
base.setLastGui(gui);
|
||||
}
|
||||
closeGui();
|
||||
gui = base;
|
||||
if(gui != null)
|
||||
{
|
||||
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
gui.onInit();
|
||||
if(activeGuis[0] != null)
|
||||
{
|
||||
activeGuis[1] = activeGuis[0];
|
||||
}
|
||||
activeGuis[0] = base;
|
||||
}
|
||||
if(activeGuis[0] != null)
|
||||
{
|
||||
activeGuis[0].focus = true;
|
||||
}
|
||||
if(activeGuis[1] != null)
|
||||
{
|
||||
activeGuis[1].focus = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void closeGui()
|
||||
{
|
||||
if(gui != null)
|
||||
{
|
||||
if(gui == activeGuis[0])
|
||||
{
|
||||
activeGuis[0] = null;
|
||||
}
|
||||
if(gui == activeGuis[1])
|
||||
{
|
||||
activeGuis[1] = null;
|
||||
}
|
||||
gui.onClosed();
|
||||
gui = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowChanged(Window window)
|
||||
{
|
||||
if(gui != null)
|
||||
{
|
||||
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
gui.onScreenChanged();
|
||||
}
|
||||
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
debug.onScreenChanged();
|
||||
}
|
||||
|
||||
public void onFixedUpdate()
|
||||
{
|
||||
globalClock++;
|
||||
for(int i = 0;i < 2;i++)
|
||||
{
|
||||
if(activeGuis[i] != null)
|
||||
{
|
||||
activeGuis[i].onFixedUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void render(float particalTicks)
|
||||
{
|
||||
Vec2i offsetMouse = start();
|
||||
if(debug.isUpdating() || isReloading)
|
||||
{
|
||||
isReloading = false;
|
||||
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
debug.onScreenChanged();
|
||||
if(gui != null)
|
||||
{
|
||||
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
gui.onScreenChanged();
|
||||
}
|
||||
}
|
||||
if(activeGuis[0] != null)
|
||||
{
|
||||
activeGuis[0].baseLayer = activeGuis[1] != null ? activeGuis[1].layers : 0;
|
||||
}
|
||||
for(int i = 1;i >= 0;i--)
|
||||
{
|
||||
if(activeGuis[i] != null && (activeGuis[i] instanceof DebugOverlay || debug.isRendering()))
|
||||
{
|
||||
activeGuis[i].draw(offsetMouse.getX(), offsetMouse.getY(), particalTicks);
|
||||
}
|
||||
}
|
||||
stop();
|
||||
Cursor.INSTANCE.clearCursor(window);
|
||||
}
|
||||
|
||||
protected Vec2i start()
|
||||
{
|
||||
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
|
||||
GLUtils.DEBTH_TEST.push(false);
|
||||
GLUtils.CULL_FACE.push(false);
|
||||
GLUtils.BLEND.setFunction(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA).push(true);
|
||||
renderer.beginFrame();
|
||||
return res.getScaledMouse();
|
||||
}
|
||||
|
||||
protected void stop()
|
||||
{
|
||||
GLUtils.DEBTH_TEST.pop();
|
||||
GLUtils.DEBTH_TEST.push(true);
|
||||
renderer.endFrame();
|
||||
GLUtils.BLEND.pop();
|
||||
GLUtils.CULL_FACE.pop();
|
||||
ShaderTracker.INSTANCE.stopShader();
|
||||
}
|
||||
|
||||
public boolean onCharTyped(char character, int codePoint)
|
||||
{
|
||||
for(int i = 0;i < 2;i++)
|
||||
{
|
||||
if(activeGuis[i] != null && debug.shouldAcceptInputs(activeGuis[i]) && activeGuis[i].onKeyTyped(character, codePoint))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean onKeyPressed(int key)
|
||||
{
|
||||
for(int i = 0;i < 2;i++)
|
||||
{
|
||||
if(activeGuis[i] != null && debug.shouldAcceptInputs(activeGuis[i]) && activeGuis[i].onKeyPressed(key))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onMouseEvent(MouseEvent event)
|
||||
{
|
||||
if(!onMouseEventInternal(event))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(activeGuis[0] != null && !event.isCanceled() && debug.shouldAcceptInputs(activeGuis[0]))
|
||||
{
|
||||
activeGuis[0].onMouseEvent(event);
|
||||
}
|
||||
if(activeGuis[1] != null && !event.isCanceled() && debug.shouldAcceptInputs(activeGuis[1]))
|
||||
{
|
||||
activeGuis[1].onMouseEvent(event);
|
||||
if(event.isCanceled())
|
||||
{
|
||||
GuiBase base = activeGuis[0];
|
||||
activeGuis[0] = activeGuis[1];
|
||||
activeGuis[1] = base;
|
||||
if(base != null)
|
||||
{
|
||||
base.onFocusLost();
|
||||
base.baseLayer = 0;
|
||||
base.layers = 0;
|
||||
}
|
||||
if(activeGuis[0] != null)
|
||||
{
|
||||
activeGuis[0].focus = true;
|
||||
}
|
||||
if(activeGuis[1] != null)
|
||||
{
|
||||
activeGuis[1].focus = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
event.convertToOrigin();
|
||||
}
|
||||
|
||||
protected boolean onMouseEventInternal(MouseEvent event)
|
||||
{
|
||||
event.convertToScreenCoords(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isAllowingMovement()
|
||||
{
|
||||
return gui == null || gui.isAllowingMovement();
|
||||
}
|
||||
|
||||
public DebugOverlay getDebug()
|
||||
{
|
||||
return debug;
|
||||
}
|
||||
|
||||
public boolean isRenderUIBoxes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public GuiShader getShader()
|
||||
{
|
||||
return shader;
|
||||
}
|
||||
|
||||
public UIRenderer getRenderer()
|
||||
{
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public FontRenderer getFont()
|
||||
{
|
||||
return font;
|
||||
}
|
||||
|
||||
public ScaledResolution getRes()
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import speiger.src.coreengine.assets.AssetLocation;
|
||||
import speiger.src.coreengine.math.vector.ints.Vec2i;
|
||||
import speiger.src.coreengine.rendering.gui.base.DebugOverlay;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.FontRenderer;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.GuiShader;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.provider.FontManager;
|
||||
import speiger.src.coreengine.rendering.input.events.KeyEvent.CharTypeEvent;
|
||||
import speiger.src.coreengine.rendering.input.events.KeyEvent.KeyPressEvent;
|
||||
import speiger.src.coreengine.rendering.input.events.MouseEvent;
|
||||
import speiger.src.coreengine.rendering.input.window.IWindowListener;
|
||||
import speiger.src.coreengine.rendering.input.window.ScaledResolution;
|
||||
import speiger.src.coreengine.rendering.input.window.Window;
|
||||
import speiger.src.coreengine.rendering.models.UniformBuffer;
|
||||
import speiger.src.coreengine.rendering.shader.ShaderTracker;
|
||||
import speiger.src.coreengine.rendering.utils.Cursor;
|
||||
import speiger.src.coreengine.rendering.utils.GLUtils;
|
||||
import speiger.src.coreengine.utils.eventbus.EventBus;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler;
|
||||
|
||||
public abstract class GuiManager implements IWindowListener
|
||||
{
|
||||
protected GuiBase[] activeGuis = new GuiBase[2];
|
||||
protected GuiBase gui;
|
||||
protected DebugOverlay debug;
|
||||
protected UIRenderer renderer = new UIRenderer(this);
|
||||
protected Window window;
|
||||
protected ScaledResolution res;
|
||||
protected long globalClock = 0L;
|
||||
protected boolean isReloading = false;
|
||||
protected FontRenderer font;
|
||||
protected GuiShader shader = ShaderTracker.INSTANCE.register(GuiShader::create, T -> shader = T);
|
||||
|
||||
public GuiManager(Window window, EventBus bus, FontManager manager)
|
||||
{
|
||||
this.window = window;
|
||||
font = manager.loadFont(AssetLocation.of("font/roboto.json"), 18.5F);
|
||||
bus.register(MouseEvent.class, this::onMouseEvent);
|
||||
bus.register(KeyPressEvent.class, (T) -> T.setCanceled(onKeyPressed(T.key)));
|
||||
bus.register(CharTypeEvent.class, (T) -> T.setCanceled(onCharTyped(T.character, T.codePoint)));
|
||||
window.addListener(this, false);
|
||||
debug = createOverlay();
|
||||
activeGuis[1] = debug;
|
||||
res = window.getUIFrame();
|
||||
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
debug.onInit();
|
||||
}
|
||||
|
||||
public abstract IProfiler getGPUProfiler();
|
||||
public abstract IProfiler getCPUProfiler();
|
||||
public abstract IProfiler getServerProfiler();
|
||||
public abstract UniformBuffer getOrthoMatrixBuffer();
|
||||
public abstract DebugOverlay createOverlay();
|
||||
|
||||
public void showGui(GuiBase base, boolean allowBack)
|
||||
{
|
||||
if(allowBack)
|
||||
{
|
||||
base.setLastGui(gui);
|
||||
}
|
||||
closeGui();
|
||||
gui = base;
|
||||
if(gui != null)
|
||||
{
|
||||
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
gui.onInit();
|
||||
if(activeGuis[0] != null)
|
||||
{
|
||||
activeGuis[1] = activeGuis[0];
|
||||
}
|
||||
activeGuis[0] = base;
|
||||
}
|
||||
if(activeGuis[0] != null)
|
||||
{
|
||||
activeGuis[0].focus = true;
|
||||
}
|
||||
if(activeGuis[1] != null)
|
||||
{
|
||||
activeGuis[1].focus = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void closeGui()
|
||||
{
|
||||
if(gui != null)
|
||||
{
|
||||
if(gui == activeGuis[0])
|
||||
{
|
||||
activeGuis[0] = null;
|
||||
}
|
||||
if(gui == activeGuis[1])
|
||||
{
|
||||
activeGuis[1] = null;
|
||||
}
|
||||
gui.onClosed();
|
||||
gui = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowChanged(Window window)
|
||||
{
|
||||
if(gui != null)
|
||||
{
|
||||
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
gui.onScreenChanged();
|
||||
}
|
||||
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
debug.onScreenChanged();
|
||||
}
|
||||
|
||||
public void onFixedUpdate()
|
||||
{
|
||||
globalClock++;
|
||||
for(int i = 0;i < 2;i++)
|
||||
{
|
||||
if(activeGuis[i] != null)
|
||||
{
|
||||
activeGuis[i].onFixedUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void render(float particalTicks)
|
||||
{
|
||||
Vec2i offsetMouse = start();
|
||||
if(debug.isUpdating() || isReloading)
|
||||
{
|
||||
isReloading = false;
|
||||
debug.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
debug.onScreenChanged();
|
||||
if(gui != null)
|
||||
{
|
||||
gui.setGuiBounds(this, res.getScaledWidth(), res.getScaledHeight());
|
||||
gui.onScreenChanged();
|
||||
}
|
||||
}
|
||||
if(activeGuis[0] != null)
|
||||
{
|
||||
activeGuis[0].baseLayer = activeGuis[1] != null ? activeGuis[1].layers : 0;
|
||||
}
|
||||
for(int i = 1;i >= 0;i--)
|
||||
{
|
||||
if(activeGuis[i] != null && (activeGuis[i] instanceof DebugOverlay || debug.isRendering()))
|
||||
{
|
||||
activeGuis[i].draw(offsetMouse.getX(), offsetMouse.getY(), particalTicks);
|
||||
}
|
||||
}
|
||||
stop();
|
||||
Cursor.INSTANCE.clearCursor(window);
|
||||
}
|
||||
|
||||
protected Vec2i start()
|
||||
{
|
||||
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
|
||||
GLUtils.DEBTH_TEST.push(false);
|
||||
GLUtils.CULL_FACE.push(false);
|
||||
GLUtils.BLEND.setFunction(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA).push(true);
|
||||
renderer.beginFrame();
|
||||
return res.getScaledMouse();
|
||||
}
|
||||
|
||||
protected void stop()
|
||||
{
|
||||
GLUtils.DEBTH_TEST.pop();
|
||||
GLUtils.DEBTH_TEST.push(true);
|
||||
renderer.endFrame();
|
||||
GLUtils.BLEND.pop();
|
||||
GLUtils.CULL_FACE.pop();
|
||||
ShaderTracker.INSTANCE.stopShader();
|
||||
}
|
||||
|
||||
public boolean onCharTyped(char character, int codePoint)
|
||||
{
|
||||
for(int i = 0;i < 2;i++)
|
||||
{
|
||||
if(activeGuis[i] != null && debug.shouldAcceptInputs(activeGuis[i]) && activeGuis[i].onKeyTyped(character, codePoint))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean onKeyPressed(int key)
|
||||
{
|
||||
for(int i = 0;i < 2;i++)
|
||||
{
|
||||
if(activeGuis[i] != null && debug.shouldAcceptInputs(activeGuis[i]) && activeGuis[i].onKeyPressed(key))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onMouseEvent(MouseEvent event)
|
||||
{
|
||||
if(!onMouseEventInternal(event))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(activeGuis[0] != null && !event.isCanceled() && debug.shouldAcceptInputs(activeGuis[0]))
|
||||
{
|
||||
activeGuis[0].onMouseEvent(event);
|
||||
}
|
||||
if(activeGuis[1] != null && !event.isCanceled() && debug.shouldAcceptInputs(activeGuis[1]))
|
||||
{
|
||||
activeGuis[1].onMouseEvent(event);
|
||||
if(event.isCanceled())
|
||||
{
|
||||
GuiBase base = activeGuis[0];
|
||||
activeGuis[0] = activeGuis[1];
|
||||
activeGuis[1] = base;
|
||||
if(base != null)
|
||||
{
|
||||
base.onFocusLost();
|
||||
base.baseLayer = 0;
|
||||
base.layers = 0;
|
||||
}
|
||||
if(activeGuis[0] != null)
|
||||
{
|
||||
activeGuis[0].focus = true;
|
||||
}
|
||||
if(activeGuis[1] != null)
|
||||
{
|
||||
activeGuis[1].focus = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
event.convertToOrigin();
|
||||
}
|
||||
|
||||
protected boolean onMouseEventInternal(MouseEvent event)
|
||||
{
|
||||
event.convertToScreenCoords(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isAllowingMovement()
|
||||
{
|
||||
return gui == null || gui.isAllowingMovement();
|
||||
}
|
||||
|
||||
public DebugOverlay getDebug()
|
||||
{
|
||||
return debug;
|
||||
}
|
||||
|
||||
public boolean isRenderUIBoxes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public GuiShader getShader()
|
||||
{
|
||||
return shader;
|
||||
}
|
||||
|
||||
public UIRenderer getRenderer()
|
||||
{
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public FontRenderer getFont()
|
||||
{
|
||||
return font;
|
||||
}
|
||||
|
||||
public ScaledResolution getRes()
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,63 +1,73 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
|
||||
public class ButtonComponent extends GuiComponent implements IButtonComponent
|
||||
{
|
||||
TextComponent text = new TextComponent();
|
||||
int color;
|
||||
|
||||
public ButtonComponent(String text, int color)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, text, color);
|
||||
}
|
||||
|
||||
public ButtonComponent(float x, float y, float width, float height, String text, int color)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.text.setText(text);
|
||||
this.color = color;
|
||||
setFlag(FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addChild(text, Constrains.parent());
|
||||
}
|
||||
|
||||
public TextComponent getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public ButtonComponent setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brigthness = getBrightness(mouseX, mouseY);
|
||||
getRenderer().setBrightness(brigthness).drawQuad(getBox(), color);
|
||||
text.setBrightness(brigthness);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onUserKey()
|
||||
{
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
|
||||
public class ButtonComponent extends GuiComponent implements IButtonComponent
|
||||
{
|
||||
TextComponent text = new TextComponent();
|
||||
int color;
|
||||
|
||||
public ButtonComponent(String text, int color)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, text, color, 1F);
|
||||
}
|
||||
|
||||
public ButtonComponent(String text, int color, float textScale)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, text, color, textScale);
|
||||
}
|
||||
|
||||
public ButtonComponent(float x, float y, float width, float height, String text, int color)
|
||||
{
|
||||
this(x, y, width, height, text, color, 1F);
|
||||
}
|
||||
|
||||
public ButtonComponent(float x, float y, float width, float height, String text, int color, float textScale)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.text.setText(text).setTextScale(textScale);
|
||||
this.color = color;
|
||||
setFlag(FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addChild(text, Constrains.parent());
|
||||
}
|
||||
|
||||
public TextComponent getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public ButtonComponent setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brigthness = getBrightness(mouseX, mouseY);
|
||||
getRenderer().setBrightness(brigthness).drawQuad(getBox(), color);
|
||||
text.setBrightness(brigthness);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onUserKey()
|
||||
{
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,122 +1,122 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.misc.ICheckBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
|
||||
public class CheckBoxComponent extends GuiComponent implements IButtonComponent, ICheckBox<CheckBoxComponent>
|
||||
{
|
||||
boolean isChecked = false;
|
||||
int color;
|
||||
RenderBuffer buffer;
|
||||
|
||||
public CheckBoxComponent(int color)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
setFlag(FLAG_SUPPORT_BINDING);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public CheckBoxComponent(int color, boolean checked)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
setFlag(FLAG_SUPPORT_BINDING);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public CheckBoxComponent(float x, float y, float width, float height, int color)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
setFlag(FLAG_SUPPORT_BINDING);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public CheckBoxComponent(float x, float y, float width, float height, int color, boolean checked)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
setFlag(FLAG_SUPPORT_BINDING);
|
||||
this.color = color;
|
||||
isChecked = checked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addCloseListener(buffer = getRenderer().createBuffer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final CheckBoxComponent setChecked(boolean isChecked)
|
||||
{
|
||||
this.isChecked = isChecked;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final CheckBoxComponent setColor(int color)
|
||||
{
|
||||
if(this.color != color)
|
||||
{
|
||||
this.color = color;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked()
|
||||
{
|
||||
return isChecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repaint()
|
||||
{
|
||||
float width = getBox().getWidth();
|
||||
float height = getBox().getHeight();
|
||||
buffer.clear();
|
||||
UIShapes.createCross(buffer, width, height, (width / 3.3F), (height / 5F), color);
|
||||
UIShapes.createCross(buffer, width, height, (width / 5F), (height / 10F), color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brightness = getActiveBrightness();
|
||||
float centerX = getBox().getCenterX();
|
||||
float centerY = getBox().getCenterY();
|
||||
getRenderer().setBrightness(brightness).drawQuad(getBox(), color).setBrightness(brightness * 0.8F).drawFrame(getBox(), color).translate(centerX, centerY);
|
||||
if(isChecked())
|
||||
{
|
||||
getRenderer().setBrightness(brightness * 0.7F).translate(0, 0, 0.001F).drawBuffers(buffer.selectionIterator(1), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.001F);
|
||||
}
|
||||
if(isTopHovered(mouseX, mouseY))
|
||||
{
|
||||
getRenderer().setBrightness(brightness * 1.3F).translate(0, 0, 0.002F).drawBuffers(buffer.selectionIterator(0), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.002F);
|
||||
}
|
||||
getRenderer().setBrightness(1F).translate(-centerX, -centerY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
isChecked = !isChecked;
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onUserKey()
|
||||
{
|
||||
isChecked = !isChecked;
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.misc.ICheckBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
|
||||
public class CheckBoxComponent extends GuiComponent implements IButtonComponent, ICheckBox<CheckBoxComponent>
|
||||
{
|
||||
boolean isChecked = false;
|
||||
int color;
|
||||
RenderBuffer buffer;
|
||||
|
||||
public CheckBoxComponent(int color)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
setFlag(FLAG_SUPPORT_BINDING);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public CheckBoxComponent(int color, boolean checked)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
setFlag(FLAG_SUPPORT_BINDING);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public CheckBoxComponent(float x, float y, float width, float height, int color)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
setFlag(FLAG_SUPPORT_BINDING);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public CheckBoxComponent(float x, float y, float width, float height, int color, boolean checked)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
setFlag(FLAG_SUPPORT_BINDING);
|
||||
this.color = color;
|
||||
isChecked = checked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
onClose(buffer = getRenderer().createBuffer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final CheckBoxComponent setChecked(boolean isChecked)
|
||||
{
|
||||
this.isChecked = isChecked;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final CheckBoxComponent setColor(int color)
|
||||
{
|
||||
if(this.color != color)
|
||||
{
|
||||
this.color = color;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked()
|
||||
{
|
||||
return isChecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repaint()
|
||||
{
|
||||
float width = getBox().getWidth();
|
||||
float height = getBox().getHeight();
|
||||
buffer.clear();
|
||||
UIShapes.createCross(buffer, width, height, (width / 3.3F), (height / 5F), color);
|
||||
UIShapes.createCross(buffer, width, height, (width / 5F), (height / 10F), color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brightness = getActiveBrightness();
|
||||
float centerX = getBox().getCenterX();
|
||||
float centerY = getBox().getCenterY();
|
||||
getRenderer().setBrightness(brightness).drawQuad(getBox(), color).setBrightness(brightness * 0.8F).drawFrame(getBox(), color).translate(centerX, centerY);
|
||||
if(isChecked())
|
||||
{
|
||||
getRenderer().setBrightness(brightness * 0.7F).translate(0, 0, 0.001F).drawBuffers(buffer.selectionIterator(1), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.001F);
|
||||
}
|
||||
if(isTopHovered(mouseX, mouseY))
|
||||
{
|
||||
getRenderer().setBrightness(brightness * 1.3F).translate(0, 0, 0.002F).drawBuffers(buffer.selectionIterator(0), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.002F);
|
||||
}
|
||||
getRenderer().setBrightness(1F).translate(-centerX, -centerY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
isChecked = !isChecked;
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onUserKey()
|
||||
{
|
||||
isChecked = !isChecked;
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +1,61 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
|
||||
public class LabelComponent extends GuiComponent
|
||||
{
|
||||
TextComponent text = new TextComponent();
|
||||
int color;
|
||||
|
||||
public LabelComponent(String text, int color)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, text, color);
|
||||
}
|
||||
|
||||
public LabelComponent(float x, float y, float width, float height, String text, int color)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.text.setText(text);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public TextComponent getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public LabelComponent setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getColor()
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addChild(text, Constrains.parent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
getRenderer().drawQuad(getBox(), color);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
|
||||
public class LabelComponent extends GuiComponent
|
||||
{
|
||||
TextComponent text = new TextComponent();
|
||||
int color;
|
||||
|
||||
public LabelComponent(String text, int color)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, text, color);
|
||||
}
|
||||
|
||||
public LabelComponent(String text, int color, float textScale)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, text, color, textScale);
|
||||
}
|
||||
|
||||
public LabelComponent(float x, float y, float width, float height, String text, int color)
|
||||
{
|
||||
this(x, y, width, height, text, color, 1F);
|
||||
}
|
||||
|
||||
public LabelComponent(float x, float y, float width, float height, String text, int color, float textScale)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.text.setText(text).setTextScale(textScale);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public TextComponent getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public LabelComponent setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getColor()
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addChild(text, Constrains.parent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
getRenderer().drawQuad(getBox(), color);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,21 +1,47 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
|
||||
public class PanelComponent extends GuiComponent
|
||||
{
|
||||
public PanelComponent()
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
}
|
||||
|
||||
public PanelComponent(float x, float y, float width, float height)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
|
||||
public class PanelComponent extends GuiComponent
|
||||
{
|
||||
public static final int FLAG_ENABLE_SCISSORS = 1 << 20;
|
||||
|
||||
public PanelComponent()
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
}
|
||||
|
||||
public PanelComponent(float x, float y, float width, float height)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
}
|
||||
|
||||
public PanelComponent setScissors(boolean value)
|
||||
{
|
||||
setFlag(FLAG_ENABLE_SCISSORS, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isScissoring()
|
||||
{
|
||||
return isFlagSet(FLAG_ENABLE_SCISSORS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderChildren(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
if(isFlagSet(FLAG_ENABLE_SCISSORS))
|
||||
{
|
||||
enableScissors(getBox());
|
||||
super.renderChildren(mouseX, mouseY, particalTicks);
|
||||
disableScissors();
|
||||
return;
|
||||
}
|
||||
super.renderChildren(mouseX, mouseY, particalTicks);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,170 +1,176 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
import speiger.src.coreengine.rendering.tesselation.Tesselator;
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexType;
|
||||
import speiger.src.coreengine.rendering.utils.GLUtils;
|
||||
|
||||
public class PieComponent extends GuiComponent
|
||||
{
|
||||
public static final int FLAG_AUTO_UPDATE = 1 << 20;
|
||||
RenderBuffer buffer;
|
||||
Supplier<List<IPieIndex>> parts;
|
||||
int maxSteps;
|
||||
|
||||
public PieComponent(int maxSteps, Supplier<List<IPieIndex>> parts)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.maxSteps = maxSteps;
|
||||
this.parts = parts;
|
||||
}
|
||||
|
||||
public PieComponent(float x, float y, float width, float height, int maxSteps, Supplier<List<IPieIndex>> parts)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.maxSteps = maxSteps;
|
||||
this.parts = parts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addCloseListener(buffer = getRenderer().createBuffer());
|
||||
}
|
||||
|
||||
public final PieComponent setAutoUpdate(boolean value)
|
||||
{
|
||||
setFlag(FLAG_AUTO_UPDATE, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final boolean isAutoUpdating()
|
||||
{
|
||||
return isFlagSet(FLAG_AUTO_UPDATE);
|
||||
}
|
||||
|
||||
public int getMaxSteps()
|
||||
{
|
||||
return maxSteps;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fixedUpdateSelf()
|
||||
{
|
||||
if(isAutoUpdating())
|
||||
{
|
||||
createPie();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repaint()
|
||||
{
|
||||
createPie();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float centerX = getBox().getCenterX();
|
||||
float centerY = getBox().getCenterY();
|
||||
getRenderer().setBrightness(getActiveBrightness()).translate(centerX, centerY).flush();
|
||||
GLUtils.DEBTH_TEST.push(true);
|
||||
getRenderer().drawBuffers(buffer, 0F, 0F).flush();
|
||||
GLUtils.DEBTH_TEST.pop();
|
||||
getRenderer().translate(-centerX, -centerY).setBrightness(1F);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void createPie()
|
||||
{
|
||||
buffer.clear();
|
||||
if(parts == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float xSize = getBox().getWidth() / 2F;
|
||||
float ySize = getBox().getHeight() / 2F;
|
||||
float extra = getBox().getHeight() / 10F;
|
||||
float value = -3.17F;
|
||||
float spaceScale = 0.0495F * (127.0F / maxSteps);
|
||||
List<IPieIndex> indexes = parts.get();
|
||||
int stepsDone = 0;
|
||||
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI);
|
||||
for(int j = indexes.size()-1;j>=0;j--)
|
||||
{
|
||||
IPieIndex pieIndex = indexes.get(j);
|
||||
int steps = j == 0 ? maxSteps - stepsDone : pieIndex.getSteps();
|
||||
int color = pieIndex.getColor();
|
||||
int darker = ColorUtils.darker(color);
|
||||
tes.offset(0F, 0F, 0.01F);
|
||||
for(int i = 0;i<steps;i++)
|
||||
{
|
||||
int index = i + stepsDone;
|
||||
tes.pos(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(MathUtils.sin(value + spaceScale * index) * xSize, MathUtils.cos(value + spaceScale * index) * ySize * 0.5F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
index++;
|
||||
tes.pos(MathUtils.sin(value + spaceScale * index) * xSize, MathUtils.cos(value + spaceScale * index) * ySize * 0.5F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
}
|
||||
tes.offset(0F, 0F, -0.01F);
|
||||
for(int i = 0;i<steps;i++)
|
||||
{
|
||||
int index = i + stepsDone;
|
||||
float x = MathUtils.sin(value + spaceScale * index) * xSize;
|
||||
float y = MathUtils.cos(value + spaceScale * index) * ySize * 0.5F;
|
||||
tes.pos(x, y, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
index++;
|
||||
float nextX = MathUtils.sin(value + spaceScale * index) * xSize;
|
||||
float nextY = MathUtils.cos(value + spaceScale * index) * ySize * 0.5F;
|
||||
tes.pos(nextX, nextY + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
tes.pos(x, y + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
tes.pos(nextX, nextY, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
tes.pos(nextX, nextY + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
tes.pos(x, y, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
}
|
||||
stepsDone += steps;
|
||||
}
|
||||
buffer.finishShape(0);
|
||||
}
|
||||
|
||||
public static interface IPieIndex
|
||||
{
|
||||
public int getSteps();
|
||||
|
||||
public int getColor();
|
||||
}
|
||||
|
||||
public static class PieIndex implements IPieIndex
|
||||
{
|
||||
int steps;
|
||||
int color;
|
||||
|
||||
public PieIndex(int steps, int color)
|
||||
{
|
||||
this.steps = steps;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSteps()
|
||||
{
|
||||
return steps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor()
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
import speiger.src.coreengine.rendering.tesselation.Tesselator;
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexType;
|
||||
import speiger.src.coreengine.rendering.utils.GLUtils;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.ProfilerData;
|
||||
|
||||
public class PieComponent extends GuiComponent
|
||||
{
|
||||
public static final int FLAG_AUTO_UPDATE = 1 << 20;
|
||||
RenderBuffer buffer;
|
||||
Supplier<List<IPieIndex>> parts;
|
||||
int maxSteps;
|
||||
|
||||
public PieComponent(int maxSteps, Supplier<List<IPieIndex>> parts)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.maxSteps = maxSteps;
|
||||
this.parts = parts;
|
||||
}
|
||||
|
||||
public PieComponent(float x, float y, float width, float height, int maxSteps, Supplier<List<IPieIndex>> parts)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.maxSteps = maxSteps;
|
||||
this.parts = parts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
onClose(buffer = getRenderer().createBuffer());
|
||||
}
|
||||
|
||||
public final PieComponent setAutoUpdate(boolean value)
|
||||
{
|
||||
setFlag(FLAG_AUTO_UPDATE, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final boolean isAutoUpdating()
|
||||
{
|
||||
return isFlagSet(FLAG_AUTO_UPDATE);
|
||||
}
|
||||
|
||||
public int getMaxSteps()
|
||||
{
|
||||
return maxSteps;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fixedUpdateSelf()
|
||||
{
|
||||
if(isAutoUpdating())
|
||||
{
|
||||
createPie();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repaint()
|
||||
{
|
||||
createPie();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float centerX = getBox().getCenterX();
|
||||
float centerY = getBox().getCenterY();
|
||||
getRenderer().setBrightness(getActiveBrightness()).translate(centerX, centerY).flush();
|
||||
GLUtils.DEBTH_TEST.push(true);
|
||||
getRenderer().drawBuffers(buffer, 0F, 0F).flush();
|
||||
GLUtils.DEBTH_TEST.pop();
|
||||
getRenderer().translate(-centerX, -centerY).setBrightness(1F);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void createPie()
|
||||
{
|
||||
buffer.clear();
|
||||
if(parts == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float xSize = getBox().getWidth() / 2F;
|
||||
float ySize = getBox().getHeight() / 2F;
|
||||
float extra = getBox().getHeight() / 10F;
|
||||
float value = -3.14F;
|
||||
float spaceScale = 0.0495F * (127.0F / maxSteps);
|
||||
List<IPieIndex> indexes = parts.get();
|
||||
int stepsDone = 0;
|
||||
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI);
|
||||
for(int j = indexes.size()-1;j>=0;j--)
|
||||
{
|
||||
IPieIndex pieIndex = indexes.get(j);
|
||||
int steps = j == 0 ? maxSteps - stepsDone : pieIndex.getSteps();
|
||||
int color = pieIndex.getColor();
|
||||
int darker = ColorUtils.darker(color);
|
||||
tes.offset(0F, 0F, 0.01F);
|
||||
for(int i = 0;i<steps;i++)
|
||||
{
|
||||
int index = i + stepsDone;
|
||||
tes.pos(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(MathUtils.sin(value + spaceScale * index) * xSize, MathUtils.cos(value + spaceScale * index) * ySize * 0.5F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
index++;
|
||||
tes.pos(MathUtils.sin(value + spaceScale * index) * xSize, MathUtils.cos(value + spaceScale * index) * ySize * 0.5F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
}
|
||||
tes.offset(0F, 0F, -0.01F);
|
||||
for(int i = 0;i<steps;i++)
|
||||
{
|
||||
int index = i + stepsDone;
|
||||
float x = MathUtils.sin(value + spaceScale * index) * xSize;
|
||||
float y = MathUtils.cos(value + spaceScale * index) * ySize * 0.5F;
|
||||
tes.pos(x, y, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
index++;
|
||||
float nextX = MathUtils.sin(value + spaceScale * index) * xSize;
|
||||
float nextY = MathUtils.cos(value + spaceScale * index) * ySize * 0.5F;
|
||||
tes.pos(nextX, nextY + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
tes.pos(x, y + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
tes.pos(nextX, nextY, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
tes.pos(nextX, nextY + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
tes.pos(x, y, 0F).tex(0F, 0F).color4f(darker).endVertex();
|
||||
}
|
||||
stepsDone += steps;
|
||||
}
|
||||
buffer.finishShape(0);
|
||||
}
|
||||
|
||||
public static interface IPieIndex
|
||||
{
|
||||
public int getSteps();
|
||||
|
||||
public int getColor();
|
||||
}
|
||||
|
||||
public static class PieIndex implements IPieIndex
|
||||
{
|
||||
int steps;
|
||||
int color;
|
||||
|
||||
public PieIndex(ProfilerData data)
|
||||
{
|
||||
this(MathUtils.floor(data.getEffect() * 1.28D), data.getColor());
|
||||
}
|
||||
|
||||
public PieIndex(int steps, int color)
|
||||
{
|
||||
this.steps = steps;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSteps()
|
||||
{
|
||||
return steps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor()
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,122 +1,159 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.IntSupplier;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.ParentBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
|
||||
|
||||
public class ProgressBarComponent extends GuiComponent
|
||||
{
|
||||
IGuiBox inner = new ParentBox(1F);
|
||||
TextComponent text = new TextComponent();
|
||||
int color;
|
||||
int value;
|
||||
int max;
|
||||
IntFunction<String> name;
|
||||
IntSupplier valueGenerator;
|
||||
|
||||
public ProgressBarComponent(int color, int value, int max)
|
||||
{
|
||||
this(color, value, max, null);
|
||||
}
|
||||
|
||||
public ProgressBarComponent(int color, int value, int max, IntFunction<String> name)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, color, value, max, name);
|
||||
}
|
||||
|
||||
public ProgressBarComponent(float x, float y, float width, float height, int color, int value, int max)
|
||||
{
|
||||
this(x, y, width, height, color, value, max, null);
|
||||
}
|
||||
|
||||
public ProgressBarComponent(float x, float y, float width, float height, int color, int value, int max, IntFunction<String> name)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.name = name;
|
||||
setColor(color);
|
||||
setMax(max);
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addBox(inner);
|
||||
text.setZOffset(0.1F);
|
||||
text.setText(stringify());
|
||||
addChild(text, Constrains.parent());
|
||||
}
|
||||
|
||||
public TextComponent getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public ProgressBarComponent setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProgressBarComponent setValueGenerator(IntSupplier valueGenerator)
|
||||
{
|
||||
this.valueGenerator = valueGenerator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProgressBarComponent setValue(int newValue)
|
||||
{
|
||||
if(value != newValue)
|
||||
{
|
||||
value = newValue;
|
||||
text.setText(stringify());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProgressBarComponent setMax(int newMax)
|
||||
{
|
||||
if(max != newMax)
|
||||
{
|
||||
max = newMax;
|
||||
if(value > max) setValue(max);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
protected String stringify()
|
||||
{
|
||||
if(name != null) return name.apply(value);
|
||||
else if(max == 0) return "0%";
|
||||
return Integer.toString((int)(((float)value / (float)max) * 100F))+"%";
|
||||
}
|
||||
|
||||
protected float getProgress()
|
||||
{
|
||||
return max == 0 ? 0F : (float)value / (float)max;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fixedUpdateSelf()
|
||||
{
|
||||
if(valueGenerator != null) setValue(valueGenerator.getAsInt());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float extra = (inner.getMaxX() - inner.getMinX()) * getProgress();
|
||||
UIRenderer render = getRenderer();
|
||||
render.setBrightness(getActiveBrightness() * 0.75F).drawQuad(getBox(), color);
|
||||
render.setBrightness(getActiveBrightness()).drawQuad(inner, 0.01F, color);
|
||||
render.setBrightness(getActiveBrightness() * 1.25F).drawQuad(inner.getMinX(), inner.getMinY(), inner.getMinX() + extra, inner.getMaxY(), 0.02F, color);
|
||||
text.setBrightness(getActiveBrightness());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.IntSupplier;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.ParentBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
|
||||
|
||||
public class ProgressBarComponent extends GuiComponent
|
||||
{
|
||||
IGuiBox inner = new ParentBox(1F);
|
||||
TextComponent text = new TextComponent();
|
||||
int color;
|
||||
int value;
|
||||
int max;
|
||||
IntFunction<String> name;
|
||||
IntSupplier valueGenerator;
|
||||
|
||||
public ProgressBarComponent(int color, int value, int max)
|
||||
{
|
||||
this(color, value, max, null);
|
||||
}
|
||||
|
||||
public ProgressBarComponent(int color, float textScale, int value, int max)
|
||||
{
|
||||
this(color, textScale, value, max, null);
|
||||
}
|
||||
|
||||
public ProgressBarComponent(int color, int value, int max, IntFunction<String> name)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, color, value, max, name);
|
||||
}
|
||||
|
||||
public ProgressBarComponent(int color, float textScale, int value, int max, IntFunction<String> name)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, color, textScale, value, max, name);
|
||||
}
|
||||
|
||||
public ProgressBarComponent(float x, float y, float width, float height, int color, int value, int max)
|
||||
{
|
||||
this(x, y, width, height, color, value, max, null);
|
||||
}
|
||||
|
||||
public ProgressBarComponent(float x, float y, float width, float height, int color, float textScale, int value, int max)
|
||||
{
|
||||
this(x, y, width, height, color, textScale, value, max, null);
|
||||
}
|
||||
|
||||
public ProgressBarComponent(float x, float y, float width, float height, int color, int value, int max, IntFunction<String> name)
|
||||
{
|
||||
this(x, y, width, height, color, 1F, value, max, name);
|
||||
}
|
||||
|
||||
public ProgressBarComponent(float x, float y, float width, float height, int color, float textScale, int value, int max, IntFunction<String> name)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.name = name;
|
||||
text.setTextScale(textScale);
|
||||
setColor(color);
|
||||
setMax(max);
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addBox(inner);
|
||||
text.setZOffset(0.1F);
|
||||
text.setText(stringify());
|
||||
addChild(text, Constrains.parent());
|
||||
}
|
||||
|
||||
public TextComponent getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public ProgressBarComponent setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProgressBarComponent setValueGenerator(IntSupplier valueGenerator)
|
||||
{
|
||||
this.valueGenerator = valueGenerator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProgressBarComponent setTextGenerator(IntFunction<String> name)
|
||||
{
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProgressBarComponent setValue(int newValue)
|
||||
{
|
||||
if(value != newValue)
|
||||
{
|
||||
value = newValue;
|
||||
text.setText(stringify());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProgressBarComponent setMax(int newMax)
|
||||
{
|
||||
if(max != newMax)
|
||||
{
|
||||
max = newMax;
|
||||
if(value > max) setValue(max);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
protected String stringify()
|
||||
{
|
||||
if(name != null) return name.apply(value);
|
||||
else if(max == 0) return "0%";
|
||||
return Integer.toString((int)(((float)value / (float)max) * 100F))+"%";
|
||||
}
|
||||
|
||||
protected float getProgress()
|
||||
{
|
||||
return max == 0 ? 0F : (float)value / (float)max;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public int getMax()
|
||||
{
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fixedUpdateSelf()
|
||||
{
|
||||
if(valueGenerator != null) setValue(valueGenerator.getAsInt());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float extra = (inner.getMaxX() - inner.getMinX()) * getProgress();
|
||||
UIRenderer render = getRenderer();
|
||||
render.setBrightness(getActiveBrightness() * 0.75F).drawQuad(getBox(), color);
|
||||
render.setBrightness(getActiveBrightness()).drawQuad(inner, 0.01F, color);
|
||||
render.setBrightness(getActiveBrightness() * 1.25F).drawQuad(inner.getMinX(), inner.getMinY(), inner.getMinX() + extra, inner.getMaxY(), 0.02F, color);
|
||||
text.setBrightness(getActiveBrightness());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,243 +1,243 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
|
||||
public class ScrollBarComponent extends GuiComponent implements IButtonComponent
|
||||
{
|
||||
public static final int FLAG_HORIZONTAL = 1024;
|
||||
public static final int FLAG_INVERTED = 2048;
|
||||
int color;
|
||||
float lastMouse = -1;
|
||||
int current;
|
||||
int max;
|
||||
|
||||
public ScrollBarComponent(int color)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public ScrollBarComponent(int color, int max)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public ScrollBarComponent(int color, int max, int current)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
this.max = max;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public ScrollBarComponent(float x, float y, float width, float height, int color)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public ScrollBarComponent(float x, float y, float width, float height, int color, int max)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public ScrollBarComponent(float x, float y, float width, float height, int color, int max, int current)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
this.max = max;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ScrollBarComponent setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScrollBarComponent setScrollMax(int max)
|
||||
{
|
||||
this.max = max;
|
||||
return addScroll(0);
|
||||
}
|
||||
|
||||
public ScrollBarComponent addScroll(int add)
|
||||
{
|
||||
return setScrollCurrent(current + add);
|
||||
}
|
||||
|
||||
public ScrollBarComponent setScrollEnd()
|
||||
{
|
||||
return setScrollCurrent(max);
|
||||
}
|
||||
|
||||
public ScrollBarComponent setScrollStart()
|
||||
{
|
||||
return setScrollCurrent(0);
|
||||
}
|
||||
|
||||
public ScrollBarComponent setScrollCurrent(int current)
|
||||
{
|
||||
this.current = (int)MathUtils.clamp(0F, Math.max(0, max - getBaseRange()), current);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected int getCurrent()
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
protected void setCurrent(int value)
|
||||
{
|
||||
current = value;
|
||||
}
|
||||
|
||||
public ScrollBarComponent setHorizontal(boolean value)
|
||||
{
|
||||
setFlag(FLAG_HORIZONTAL, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScrollBarComponent setInverted(boolean value)
|
||||
{
|
||||
setFlag(FLAG_INVERTED, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isHorizontal()
|
||||
{
|
||||
return isFlagSet(FLAG_HORIZONTAL);
|
||||
}
|
||||
|
||||
public int getScroll()
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
public boolean isAtEnd()
|
||||
{
|
||||
return (max - getBaseRange()) <= current;
|
||||
}
|
||||
|
||||
public boolean isInUse()
|
||||
{
|
||||
return (max - getBaseRange()) > 0F;
|
||||
}
|
||||
|
||||
public float getRequiredSpace()
|
||||
{
|
||||
return (max - getBaseRange()) > 0F ? (isHorizontal() ? getBox().getHeight() : getBox().getWidth()) : 0F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComponentColliding(int mouseX, int mouseY)
|
||||
{
|
||||
return isInUse() && isHovered(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float baseRange = getBaseRange();
|
||||
float extra = max - baseRange;
|
||||
if(extra <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
IGuiBox box = getBox();
|
||||
float range = getRange();
|
||||
float min = getCurrent() * (baseRange - range) / extra;
|
||||
float brightness = getActiveBrightness();
|
||||
getRenderer().setBrightness(brightness * 0.5F).drawQuad(box, color);
|
||||
if(isHorizontal()) getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(min), box.getMinY(), box.getMinX(min + range), box.getMaxY(), 0.01F, color);
|
||||
else getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(), box.getMinY(min), box.getMaxX(), box.getMinY(min + range), 0.01F, color);
|
||||
getRenderer().setBrightness(1F);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
float baseRange = getBaseRange();
|
||||
float extra = max - baseRange;
|
||||
if(extra <= 0F)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
float range = getRange();
|
||||
float pos = (baseRange - range) / extra;
|
||||
float start = Math.max(0F, getCurrent() * pos);
|
||||
IGuiBox box = getBox();
|
||||
float currentPos = (isHorizontal() ? box.getMinX(start) : box.getMinY(start)) + ((range * box.getScale()) / 2F);
|
||||
float mouse = isHorizontal() ? mouseX : mouseY;
|
||||
if(mouse < currentPos)
|
||||
{
|
||||
setCurrent((int)Math.max(0F, getCurrent() - (((currentPos - mouse) / pos) / box.getScale())));
|
||||
}
|
||||
else if(mouse > currentPos)
|
||||
{
|
||||
setCurrent((int)Math.min(extra, getCurrent() + (((mouse - currentPos) / pos) / box.getScale())));
|
||||
}
|
||||
lastMouse = mouse;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(int mouseX, int mouseY)
|
||||
{
|
||||
if(lastMouse != -1F)
|
||||
{
|
||||
float range = getRange();
|
||||
IGuiBox box = getBox();
|
||||
float mouse = (isHorizontal() ? mouseX - box.getMinX() : mouseY - box.getMinY()) - ((range * box.getScale()) / 2F);
|
||||
float baseRange = getBaseRange();
|
||||
float extra = max - baseRange;
|
||||
setCurrent((int)MathUtils.clamp(0F, Math.max(0F, extra), (mouse / ((baseRange - range) / extra)) / box.getScale()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
lastMouse = -1F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(int scroll, int mouseX, int mouseY)
|
||||
{
|
||||
float extra = max - getBaseRange();
|
||||
if(extra > 0F)
|
||||
{
|
||||
setCurrent((int)MathUtils.clamp(0, extra, current - (scroll * (extra / 10F))));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected float getBaseRange()
|
||||
{
|
||||
return isHorizontal() ? getBox().getBaseWidth() : getBox().getBaseHeight();
|
||||
}
|
||||
|
||||
protected float getRange()
|
||||
{
|
||||
float value = getBaseRange();
|
||||
return MathUtils.clamp(10F, value, ((value * value) / max));
|
||||
}
|
||||
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
|
||||
public class ScrollBarComponent extends GuiComponent implements IButtonComponent
|
||||
{
|
||||
public static final int FLAG_HORIZONTAL = 1 << 20;
|
||||
public static final int FLAG_INVERTED = 1 << 21;
|
||||
int color;
|
||||
float lastMouse = -1;
|
||||
int current;
|
||||
int max;
|
||||
|
||||
public ScrollBarComponent(int color)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public ScrollBarComponent(int color, int max)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public ScrollBarComponent(int color, int max, int current)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
this.max = max;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public ScrollBarComponent(float x, float y, float width, float height, int color)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public ScrollBarComponent(float x, float y, float width, float height, int color, int max)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public ScrollBarComponent(float x, float y, float width, float height, int color, int max, int current)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
this.max = max;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ScrollBarComponent setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScrollBarComponent setScrollMax(int max)
|
||||
{
|
||||
this.max = max;
|
||||
return addScroll(0);
|
||||
}
|
||||
|
||||
public ScrollBarComponent addScroll(int add)
|
||||
{
|
||||
return setScrollCurrent(current + add);
|
||||
}
|
||||
|
||||
public ScrollBarComponent setScrollEnd()
|
||||
{
|
||||
return setScrollCurrent(max);
|
||||
}
|
||||
|
||||
public ScrollBarComponent setScrollStart()
|
||||
{
|
||||
return setScrollCurrent(0);
|
||||
}
|
||||
|
||||
public ScrollBarComponent setScrollCurrent(int current)
|
||||
{
|
||||
this.current = (int)MathUtils.clamp(0F, Math.max(0, max - getBaseRange()), current);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected int getCurrent()
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
protected void setCurrent(int value)
|
||||
{
|
||||
current = value;
|
||||
}
|
||||
|
||||
public ScrollBarComponent setHorizontal(boolean value)
|
||||
{
|
||||
setFlag(FLAG_HORIZONTAL, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScrollBarComponent setInverted(boolean value)
|
||||
{
|
||||
setFlag(FLAG_INVERTED, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isHorizontal()
|
||||
{
|
||||
return isFlagSet(FLAG_HORIZONTAL);
|
||||
}
|
||||
|
||||
public int getScroll()
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
public boolean isAtEnd()
|
||||
{
|
||||
return (max - getBaseRange()) <= current;
|
||||
}
|
||||
|
||||
public boolean isInUse()
|
||||
{
|
||||
return (max - getBaseRange()) > 0F;
|
||||
}
|
||||
|
||||
public float getRequiredSpace()
|
||||
{
|
||||
return (max - getBaseRange()) > 0F ? (isHorizontal() ? getBox().getHeight() : getBox().getWidth()) : 0F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComponentColliding(int mouseX, int mouseY)
|
||||
{
|
||||
return isInUse() && isHovered(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float baseRange = getBaseRange();
|
||||
float extra = max - baseRange;
|
||||
if(extra <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
IGuiBox box = getBox();
|
||||
float range = getRange();
|
||||
float min = getCurrent() * (baseRange - range) / extra;
|
||||
float brightness = getActiveBrightness();
|
||||
getRenderer().setBrightness(brightness * 0.5F).drawQuad(box, color);
|
||||
if(isHorizontal()) getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(min), box.getMinY(), box.getMinX(min + range), box.getMaxY(), 0.01F, color);
|
||||
else getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(), box.getMinY(min), box.getMaxX(), box.getMinY(min + range), 0.01F, color);
|
||||
getRenderer().setBrightness(1F);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
float baseRange = getBaseRange();
|
||||
float extra = max - baseRange;
|
||||
if(extra <= 0F)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
float range = getRange();
|
||||
float pos = (baseRange - range) / extra;
|
||||
float start = Math.max(0F, getCurrent() * pos);
|
||||
IGuiBox box = getBox();
|
||||
float currentPos = (isHorizontal() ? box.getMinX(start) : box.getMinY(start)) + ((range * box.getScale()) / 2F);
|
||||
float mouse = isHorizontal() ? mouseX : mouseY;
|
||||
if(mouse < currentPos)
|
||||
{
|
||||
setCurrent((int)Math.max(0F, getCurrent() - (((currentPos - mouse) / pos) / box.getScale())));
|
||||
}
|
||||
else if(mouse > currentPos)
|
||||
{
|
||||
setCurrent((int)Math.min(extra, getCurrent() + (((mouse - currentPos) / pos) / box.getScale())));
|
||||
}
|
||||
lastMouse = mouse;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(int mouseX, int mouseY)
|
||||
{
|
||||
if(lastMouse != -1F)
|
||||
{
|
||||
float range = getRange();
|
||||
IGuiBox box = getBox();
|
||||
float mouse = (isHorizontal() ? mouseX - box.getMinX() : mouseY - box.getMinY()) - ((range * box.getScale()) / 2F);
|
||||
float baseRange = getBaseRange();
|
||||
float extra = max - baseRange;
|
||||
setCurrent((int)MathUtils.clamp(0F, Math.max(0F, extra), (mouse / ((baseRange - range) / extra)) / box.getScale()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
lastMouse = -1F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(int scroll, int mouseX, int mouseY)
|
||||
{
|
||||
float extra = max - getBaseRange();
|
||||
if(extra > 0F)
|
||||
{
|
||||
setCurrent((int)MathUtils.clamp(0, extra, current - (scroll * (extra / 10F))));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected float getBaseRange()
|
||||
{
|
||||
return isHorizontal() ? getBox().getBaseWidth() : getBox().getBaseHeight();
|
||||
}
|
||||
|
||||
protected float getRange()
|
||||
{
|
||||
float value = getBaseRange();
|
||||
return MathUtils.clamp(10F, value, ((value * value) / max));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,96 +1,96 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ConditionalConstraint;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
|
||||
public class ScrollPanelComponent extends GuiComponent
|
||||
{
|
||||
public static final int FLAG_CORNER = 1 << 20;
|
||||
|
||||
ScrollBarComponent horizontalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY).setHorizontal(true);
|
||||
ScrollBarComponent verticalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY);
|
||||
protected PanelComponent container = new PanelComponent().setManualRenderer(true).setScissorsTest(true).cast();
|
||||
PanelComponent viewPort = new PanelComponent().setManualRenderer(true).cast();
|
||||
|
||||
public ScrollPanelComponent()
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
}
|
||||
|
||||
public ScrollPanelComponent(float x, float y, float width, float height)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addChild(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
|
||||
addChild(verticalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, false, 5F));
|
||||
viewPort.addChild(container);
|
||||
container.addChangeListener(this::recalculateSize);
|
||||
addChild(viewPort, Constrains.width(ConditionalConstraint.parent(verticalBar::isInUse, 0F, 5F)).height(ConditionalConstraint.parent(horizontalBar::isInUse, 0F, 5F)).build());
|
||||
}
|
||||
|
||||
public ScrollPanelComponent setForcedCorner(boolean value)
|
||||
{
|
||||
if(setFlag(FLAG_CORNER, value) && getGui() != null)
|
||||
{
|
||||
addConstrains(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
|
||||
addConstrains(verticalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, false, 5F));
|
||||
onChanged(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public PanelComponent getContainer()
|
||||
{
|
||||
return container;
|
||||
}
|
||||
|
||||
public PanelComponent getViewPort()
|
||||
{
|
||||
return viewPort;
|
||||
}
|
||||
|
||||
protected void recalculateSize(GuiComponent owner)
|
||||
{
|
||||
float maxX = 0F;
|
||||
float maxY = 0F;
|
||||
for(GuiComponent component : container.getChildren())
|
||||
{
|
||||
IGuiBox box = component.getBox();
|
||||
maxX = Math.max(maxX, box.getBaseX() + box.getBaseWidth());
|
||||
maxY = Math.max(maxY, box.getBaseY() + box.getBaseHeight());
|
||||
}
|
||||
horizontalBar.setScrollMax((int)maxX);
|
||||
verticalBar.setScrollMax((int)maxY);
|
||||
owner.bounds(maxX, maxY).set(-horizontalBar.getScroll(), -verticalBar.getScroll());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
super.updateSelf(mouseX, mouseY, particalTicks);
|
||||
container.set(-horizontalBar.getScroll(), -verticalBar.getScroll());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
renderChildren(mouseX, mouseY, particalTicks);
|
||||
if(container.isVisible())
|
||||
{
|
||||
enableScissors(viewPort.getBox());
|
||||
getRenderer().translate(0F, 0F, 0.1F);
|
||||
container.render(mouseX, mouseY, particalTicks);
|
||||
getRenderer().translate(0F, 0F, -0.1F);
|
||||
disableScissors();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ConditionalConstraint;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
|
||||
public class ScrollPanelComponent extends GuiComponent
|
||||
{
|
||||
public static final int FLAG_CORNER = 1 << 20;
|
||||
|
||||
ScrollBarComponent horizontalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY).setHorizontal(true);
|
||||
ScrollBarComponent verticalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY);
|
||||
protected PanelComponent container = new PanelComponent().setManualRenderer(true).setScissorsTest(true).cast();
|
||||
PanelComponent viewPort = new PanelComponent().setManualRenderer(true).cast();
|
||||
|
||||
public ScrollPanelComponent()
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
}
|
||||
|
||||
public ScrollPanelComponent(float x, float y, float width, float height)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addChild(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
|
||||
addChild(verticalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, false, 5F));
|
||||
viewPort.addChild(container);
|
||||
container.onChange(this::recalculateSize);
|
||||
addChild(viewPort, Constrains.width(ConditionalConstraint.parent(verticalBar::isInUse, 0F, 5F)).height(ConditionalConstraint.parent(horizontalBar::isInUse, 0F, 5F)).build());
|
||||
}
|
||||
|
||||
public ScrollPanelComponent setForcedCorner(boolean value)
|
||||
{
|
||||
if(setFlag(FLAG_CORNER, value) && getGui() != null)
|
||||
{
|
||||
addConstrains(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
|
||||
addConstrains(verticalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, false, 5F));
|
||||
onChanged(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public PanelComponent getContainer()
|
||||
{
|
||||
return container;
|
||||
}
|
||||
|
||||
public PanelComponent getViewPort()
|
||||
{
|
||||
return viewPort;
|
||||
}
|
||||
|
||||
protected void recalculateSize(GuiComponent owner)
|
||||
{
|
||||
float maxX = 0F;
|
||||
float maxY = 0F;
|
||||
for(GuiComponent component : container.getChildren())
|
||||
{
|
||||
IGuiBox box = component.getBox();
|
||||
maxX = Math.max(maxX, box.getBaseX() + box.getBaseWidth());
|
||||
maxY = Math.max(maxY, box.getBaseY() + box.getBaseHeight());
|
||||
}
|
||||
horizontalBar.setScrollMax((int)maxX);
|
||||
verticalBar.setScrollMax((int)maxY);
|
||||
owner.bounds(maxX, maxY).set(-horizontalBar.getScroll(), -verticalBar.getScroll());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
super.updateSelf(mouseX, mouseY, particalTicks);
|
||||
container.set(-horizontalBar.getScroll(), -verticalBar.getScroll());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
renderChildren(mouseX, mouseY, particalTicks);
|
||||
if(container.isVisible())
|
||||
{
|
||||
enableScissors(viewPort.getBox());
|
||||
getRenderer().translate(0F, 0F, 0.1F);
|
||||
container.render(mouseX, mouseY, particalTicks);
|
||||
getRenderer().translate(0F, 0F, -0.1F);
|
||||
disableScissors();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,109 +1,109 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ConditionalConstraint;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
|
||||
public class ScrollWindowComponent extends WindowComponent
|
||||
{
|
||||
public static final int FLAG_CORNER = 1 << 26;
|
||||
ScrollBarComponent horizontalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY).setHorizontal(true);
|
||||
ScrollBarComponent verticalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY);
|
||||
protected PanelComponent container = new PanelComponent().setManualRenderer(true).cast();
|
||||
PanelComponent viewPort = new PanelComponent().setManualRenderer(true).cast();
|
||||
|
||||
public ScrollWindowComponent(int flags, String name)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F, flags, name);
|
||||
}
|
||||
|
||||
public ScrollWindowComponent(float x, float y, float width, float height, int flags, String name)
|
||||
{
|
||||
super(x, y, width, height, flags, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
addChild(horizontalBar.addChangeListener(minimizedListener), Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
|
||||
addChild(verticalBar.addChangeListener(minimizedListener), Constrains.verticalScrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, 7.5F, 5F));
|
||||
viewPort.addChild(container);
|
||||
container.addChangeListener(this::recalculateSize).addChangeListener(minimizedListener);
|
||||
addChild(viewPort.set(0F, 7.5F), Constrains.width(ConditionalConstraint.parent(verticalBar::isInUse, 0F, 5F)).height(ConditionalConstraint.parent(horizontalBar::isInUse, 0F, 5F)).build());
|
||||
}
|
||||
|
||||
public <T extends GuiComponent> T addComponent(T comp)
|
||||
{
|
||||
return container.addChild(comp);
|
||||
}
|
||||
|
||||
public <T extends GuiComponent> T addComponent(T comp, Constrains constraints)
|
||||
{
|
||||
return container.addChild(comp, constraints);
|
||||
}
|
||||
|
||||
public PanelComponent getContainer()
|
||||
{
|
||||
return container;
|
||||
}
|
||||
|
||||
public PanelComponent getViewPort()
|
||||
{
|
||||
return viewPort;
|
||||
}
|
||||
|
||||
public ScrollWindowComponent setForcedCorner(boolean value)
|
||||
{
|
||||
if(setFlag(FLAG_CORNER, value) && getGui() != null)
|
||||
{
|
||||
addConstrains(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
|
||||
addConstrains(verticalBar, Constrains.verticalScrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, 7.5F, 5F));
|
||||
onChanged(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void recalculateSize(GuiComponent owner)
|
||||
{
|
||||
float maxX = 0F;
|
||||
float maxY = 0F;
|
||||
for(GuiComponent component : container.getChildren())
|
||||
{
|
||||
IGuiBox box = component.getBox();
|
||||
maxX = Math.max(maxX, box.getBaseX() + box.getBaseWidth());
|
||||
maxY = Math.max(maxY, box.getBaseY() + box.getBaseHeight());
|
||||
}
|
||||
horizontalBar.setScrollMax((int)maxX);
|
||||
verticalBar.setScrollMax((int)maxY);
|
||||
horizontalBar.onChanged(true);
|
||||
verticalBar.onChanged(true);
|
||||
owner.bounds(maxX, maxY).set(-horizontalBar.getScroll(), -verticalBar.getScroll());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
super.updateSelf(mouseX, mouseY, particalTicks);
|
||||
container.set(-horizontalBar.getScroll(), -verticalBar.getScroll());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
super.renderSelf(mouseX, mouseY, particalTicks);
|
||||
renderChildren(mouseX, mouseY, particalTicks);
|
||||
if(container.isVisible())
|
||||
{
|
||||
enableScissors(viewPort.getBox());
|
||||
getRenderer().translate(0F, 0F, 0.1F);
|
||||
container.render(mouseX, mouseY, particalTicks);
|
||||
getRenderer().translate(0F, 0F, -0.1F);
|
||||
disableScissors();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ConditionalConstraint;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
|
||||
public class ScrollWindowComponent extends WindowComponent
|
||||
{
|
||||
public static final int FLAG_CORNER = 1 << 26;
|
||||
ScrollBarComponent horizontalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY).setHorizontal(true);
|
||||
ScrollBarComponent verticalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY);
|
||||
protected PanelComponent container = new PanelComponent().setManualRenderer(true).cast();
|
||||
PanelComponent viewPort = new PanelComponent().setManualRenderer(true).cast();
|
||||
|
||||
public ScrollWindowComponent(int flags, String name)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F, flags, name);
|
||||
}
|
||||
|
||||
public ScrollWindowComponent(float x, float y, float width, float height, int flags, String name)
|
||||
{
|
||||
super(x, y, width, height, flags, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
addChild(horizontalBar.onChange(minimizedListener), Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
|
||||
addChild(verticalBar.onChange(minimizedListener), Constrains.verticalScrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, 7.5F, 5F));
|
||||
viewPort.addChild(container);
|
||||
container.onChange(this::recalculateSize).onChange(minimizedListener);
|
||||
addChild(viewPort.set(0F, 7.5F), Constrains.width(ConditionalConstraint.parent(verticalBar::isInUse, 0F, 5F)).height(ConditionalConstraint.parent(horizontalBar::isInUse, 0F, 5F)).build());
|
||||
}
|
||||
|
||||
public <T extends GuiComponent> T addComponent(T comp)
|
||||
{
|
||||
return container.addChild(comp);
|
||||
}
|
||||
|
||||
public <T extends GuiComponent> T addComponent(T comp, Constrains constraints)
|
||||
{
|
||||
return container.addChild(comp, constraints);
|
||||
}
|
||||
|
||||
public PanelComponent getContainer()
|
||||
{
|
||||
return container;
|
||||
}
|
||||
|
||||
public PanelComponent getViewPort()
|
||||
{
|
||||
return viewPort;
|
||||
}
|
||||
|
||||
public ScrollWindowComponent setForcedCorner(boolean value)
|
||||
{
|
||||
if(setFlag(FLAG_CORNER, value) && getGui() != null)
|
||||
{
|
||||
addConstrains(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
|
||||
addConstrains(verticalBar, Constrains.verticalScrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, 7.5F, 5F));
|
||||
onChanged(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void recalculateSize(GuiComponent owner)
|
||||
{
|
||||
float maxX = 0F;
|
||||
float maxY = 0F;
|
||||
for(GuiComponent component : container.getChildren())
|
||||
{
|
||||
IGuiBox box = component.getBox();
|
||||
maxX = Math.max(maxX, box.getBaseX() + box.getBaseWidth());
|
||||
maxY = Math.max(maxY, box.getBaseY() + box.getBaseHeight());
|
||||
}
|
||||
horizontalBar.setScrollMax((int)maxX);
|
||||
verticalBar.setScrollMax((int)maxY);
|
||||
horizontalBar.onChanged(true);
|
||||
verticalBar.onChanged(true);
|
||||
owner.bounds(maxX, maxY).set(-horizontalBar.getScroll(), -verticalBar.getScroll());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
super.updateSelf(mouseX, mouseY, particalTicks);
|
||||
container.set(-horizontalBar.getScroll(), -verticalBar.getScroll());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
super.renderSelf(mouseX, mouseY, particalTicks);
|
||||
renderChildren(mouseX, mouseY, particalTicks);
|
||||
if(container.isVisible())
|
||||
{
|
||||
enableScissors(viewPort.getBox());
|
||||
getRenderer().translate(0F, 0F, 0.1F);
|
||||
container.render(mouseX, mouseY, particalTicks);
|
||||
getRenderer().translate(0F, 0F, -0.1F);
|
||||
disableScissors();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,363 +1,363 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import speiger.src.collections.ints.collections.IntCollection;
|
||||
import speiger.src.coreengine.math.value.IValue;
|
||||
import speiger.src.coreengine.math.value.LiniarValue;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.list.SelectionEntry;
|
||||
import speiger.src.coreengine.rendering.gui.helper.Align;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
import speiger.src.coreengine.rendering.tesselation.Tesselator;
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexType;
|
||||
|
||||
public class SelectionComponent extends GuiComponent implements IButtonComponent, Consumer<GuiComponent>
|
||||
{
|
||||
public static final int FLAG_ANIMATE = 1 << 20;
|
||||
ListComponent<SelectionEntry> list = new ListComponent<SelectionEntry>().bounds(0F, 120F).setManualRenderer(true).setIgnoreBounds(true).cast();
|
||||
TextComponent text = new TextComponent().align(Align.LEFT_TOP, Align.CENTER).setTextScale(0.85F).setManualRenderer(true).cast();
|
||||
RenderBuffer buffer;
|
||||
int color;
|
||||
boolean isOpen = false;
|
||||
int selectedIndex = -1;
|
||||
int defaultIndex = -1;
|
||||
IValue animation = null;
|
||||
|
||||
public SelectionComponent(int color)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
text.setText("Select Index");
|
||||
list.setColor(color);
|
||||
}
|
||||
|
||||
public SelectionComponent(int color, Collection<String> collection)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
text.setText("Select Index");
|
||||
list.setColor(color);
|
||||
addEntries(collection);
|
||||
}
|
||||
|
||||
public SelectionComponent(float x, float y, float width, float height, int color)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
text.setText("Select Index");
|
||||
list.setColor(color);
|
||||
}
|
||||
|
||||
public SelectionComponent(float x, float y, float width, float height, int color, Collection<String> collection)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
text.setText("Select Index");
|
||||
list.setColor(color);
|
||||
addEntries(collection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
list.setEntryHeight(getGui().getFont().height()).addUserActionListener(this);
|
||||
addChild(text, Constrains.parent(21F, 0F, 10.5F, 0F));
|
||||
addChild(list, Constrains.parent(Target.X).invParent(Target.Y).parent(Target.WIDTH).build());
|
||||
addCloseListener(buffer = getRenderer().createBuffer());
|
||||
createArrow();
|
||||
}
|
||||
|
||||
public final SelectionComponent setAnimating(boolean value)
|
||||
{
|
||||
setFlag(FLAG_ANIMATE, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final boolean isAnimating()
|
||||
{
|
||||
return isFlagSet(FLAG_ANIMATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState()
|
||||
{
|
||||
list.setVisible(isOpen);
|
||||
}
|
||||
|
||||
public TextComponent getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public ListComponent<SelectionEntry> getList()
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
public SelectionComponent addEntry(String s)
|
||||
{
|
||||
list.add(new SelectionEntry(s));
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent addEntries(Collection<String> collection)
|
||||
{
|
||||
for(String s : collection)
|
||||
{
|
||||
list.add(new SelectionEntry(s));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent updateEntry(int index, String newName)
|
||||
{
|
||||
list.get(index).setText(newName);
|
||||
if(index == selectedIndex)
|
||||
{
|
||||
updateSelection();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent removeEntry(String s)
|
||||
{
|
||||
for(int i = 0,m=list.size();i<m;i++)
|
||||
{
|
||||
if(list.get(i).getText().equals(s))
|
||||
{
|
||||
list.remove(i);
|
||||
if(selectedIndex == i)
|
||||
{
|
||||
updateSelection();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent removeIndex(int index)
|
||||
{
|
||||
if(list.remove(index) != null && selectedIndex == index)
|
||||
{
|
||||
updateSelection();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent removeIndexes(IntCollection values)
|
||||
{
|
||||
if(list.removeAll(values) && values.contains(selectedIndex))
|
||||
{
|
||||
updateSelection();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent setDefaultIndex(int index)
|
||||
{
|
||||
defaultIndex = index;
|
||||
if(index != -1 && selectedIndex == -1)
|
||||
{
|
||||
list.setSelectedIndex(index);
|
||||
updateSelection();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent setSelectedIndex(int index)
|
||||
{
|
||||
list.setSelectedIndex(index);
|
||||
updateSelection();
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getSelectedIndex()
|
||||
{
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
public String getSelectedValue()
|
||||
{
|
||||
return list.get(selectedIndex).getText();
|
||||
}
|
||||
|
||||
protected void createArrow()
|
||||
{
|
||||
if(buffer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
buffer.clear();
|
||||
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI).setOffset(-6F, -6F, 0F);
|
||||
tes.pos(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(0F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(0F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(6F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(6F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(12F, 6F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.setOffset(0F, 0F, 0F);
|
||||
buffer.finishShape(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
if(animation != null)
|
||||
{
|
||||
animation.update(particalTicks);
|
||||
if(animation.isDone())
|
||||
{
|
||||
if(animation.get() < 1F)
|
||||
{
|
||||
isOpen = false;
|
||||
list.setVisible(false);
|
||||
}
|
||||
animation = null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brightness = getActiveBrightness();
|
||||
IGuiBox box = getBox();
|
||||
float minX = box.getMinX(10F);
|
||||
float minY = box.getMinY(10F);
|
||||
float currentZ = getRenderer().getCurrentZ();
|
||||
float rotation = animation != null ? animation.get() : (isOpen ? 90 : 0);
|
||||
UIRenderer render = getRenderer();
|
||||
render.setBrightness(brightness).drawQuad(box, color);
|
||||
render.setBrightness(brightness * 0.7F).drawQuad(box.getMinX(), box.getMinY(), box.getMinX(20F), box.getMaxY(), 0.001F, color);
|
||||
render.setFastTransform(false).setBrightness(brightness).translate(minX, minY, 0.02F + currentZ);
|
||||
render.scale(box.getScale()).rotateZ(rotation).drawBuffers(buffer, 0, 0).resetTransform().setFastTransform(true).translate(0F, 0F, 0.01F).setBrightness(1F);
|
||||
text.render(mouseX, mouseY, particalTicks);
|
||||
if(animation != null)
|
||||
{
|
||||
float progress = animation.get() / 90F;
|
||||
box = list.getBox();
|
||||
enableScissors(box.getMinX(), box.getMinY(), box.getWidth(), box.getHeight() * progress);
|
||||
list.render(mouseX, mouseY, particalTicks);
|
||||
disableScissors();
|
||||
}
|
||||
else if(isOpen)
|
||||
{
|
||||
list.render(mouseX, mouseY, particalTicks);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComponentColliding(int mouseX, int mouseY)
|
||||
{
|
||||
return isMouseOver(mouseX, mouseY) || (isOpen && list.isComponentColliding(mouseX, mouseY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidButton(int button)
|
||||
{
|
||||
return button == 0 || button == 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
//TODO look how to move into OnRelease
|
||||
if(isOpen && button == 0)
|
||||
{
|
||||
if(isMouseOver(mouseX, mouseY) && animation == null)
|
||||
{
|
||||
close();
|
||||
}
|
||||
return animation == null && list.onClick(button, mouseX, mouseY);
|
||||
}
|
||||
if(button == 2)
|
||||
{
|
||||
list.setSelectedIndex(-1);
|
||||
updateSelection();
|
||||
return true;
|
||||
}
|
||||
isOpen = true;
|
||||
list.setVisible(true);
|
||||
if(isAnimating())
|
||||
{
|
||||
animation = new LiniarValue(2F, 0F, 90F).setSmooth();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(int mouseX, int mouseY)
|
||||
{
|
||||
return isOpen && animation == null && list.onDrag(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
if(isOpen && animation == null)
|
||||
{
|
||||
list.onRelease(button, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(int scroll, int mouseX, int mouseY)
|
||||
{
|
||||
return isOpen && animation == null && list.onScroll(scroll, mouseX, mouseY);
|
||||
}
|
||||
|
||||
protected void close()
|
||||
{
|
||||
if(isAnimating())
|
||||
{
|
||||
animation = new LiniarValue(2F, 90F, 0F).setSmooth();
|
||||
}
|
||||
else
|
||||
{
|
||||
isOpen = false;
|
||||
list.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent t)
|
||||
{
|
||||
updateSelection();
|
||||
close();
|
||||
}
|
||||
|
||||
protected void updateSelection()
|
||||
{
|
||||
if(list.hasSelected())
|
||||
{
|
||||
selectedIndex = list.getSelectedIndex();
|
||||
text.setText(list.get(selectedIndex).getText());
|
||||
}
|
||||
else if(defaultIndex != -1)
|
||||
{
|
||||
list.setSelectedIndex(defaultIndex);
|
||||
selectedIndex = list.getSelectedIndex();
|
||||
text.setText(list.get(selectedIndex).getText());
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedIndex = -1;
|
||||
text.setText("Select Index");
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import speiger.src.collections.ints.collections.IntCollection;
|
||||
import speiger.src.coreengine.math.value.IValue;
|
||||
import speiger.src.coreengine.math.value.LiniarValue;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.list.SelectionEntry;
|
||||
import speiger.src.coreengine.rendering.gui.helper.Align;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
import speiger.src.coreengine.rendering.tesselation.Tesselator;
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexType;
|
||||
|
||||
public class SelectionComponent extends GuiComponent implements IButtonComponent, Consumer<GuiComponent>
|
||||
{
|
||||
public static final int FLAG_ANIMATE = 1 << 20;
|
||||
ListComponent<SelectionEntry> list = new ListComponent<SelectionEntry>().bounds(0F, 120F).setManualRenderer(true).setIgnoreBounds(true).cast();
|
||||
TextComponent text = new TextComponent().align(Align.LEFT_TOP, Align.CENTER).setTextScale(0.85F).setManualRenderer(true).cast();
|
||||
RenderBuffer buffer;
|
||||
int color;
|
||||
boolean isOpen = false;
|
||||
int selectedIndex = -1;
|
||||
int defaultIndex = -1;
|
||||
IValue animation = null;
|
||||
|
||||
public SelectionComponent(int color)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
text.setText("Select Index");
|
||||
list.setColor(color);
|
||||
}
|
||||
|
||||
public SelectionComponent(int color, Collection<String> collection)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
text.setText("Select Index");
|
||||
list.setColor(color);
|
||||
addEntries(collection);
|
||||
}
|
||||
|
||||
public SelectionComponent(float x, float y, float width, float height, int color)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
text.setText("Select Index");
|
||||
list.setColor(color);
|
||||
}
|
||||
|
||||
public SelectionComponent(float x, float y, float width, float height, int color, Collection<String> collection)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
text.setText("Select Index");
|
||||
list.setColor(color);
|
||||
addEntries(collection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
list.setEntryHeight(getGui().getFont().height()).onAction(this);
|
||||
addChild(text, Constrains.parent(21F, 0F, 10.5F, 0F));
|
||||
addChild(list, Constrains.parent(Target.X).invParent(Target.Y).parent(Target.WIDTH).build());
|
||||
onClose(buffer = getRenderer().createBuffer());
|
||||
createArrow();
|
||||
}
|
||||
|
||||
public final SelectionComponent setAnimating(boolean value)
|
||||
{
|
||||
setFlag(FLAG_ANIMATE, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final boolean isAnimating()
|
||||
{
|
||||
return isFlagSet(FLAG_ANIMATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState()
|
||||
{
|
||||
list.setVisible(isOpen);
|
||||
}
|
||||
|
||||
public TextComponent getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public ListComponent<SelectionEntry> getList()
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
public SelectionComponent addEntry(String s)
|
||||
{
|
||||
list.add(new SelectionEntry(s));
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent addEntries(Collection<String> collection)
|
||||
{
|
||||
for(String s : collection)
|
||||
{
|
||||
list.add(new SelectionEntry(s));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent updateEntry(int index, String newName)
|
||||
{
|
||||
list.get(index).setText(newName);
|
||||
if(index == selectedIndex)
|
||||
{
|
||||
updateSelection();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent removeEntry(String s)
|
||||
{
|
||||
for(int i = 0,m=list.size();i<m;i++)
|
||||
{
|
||||
if(list.get(i).getText().equals(s))
|
||||
{
|
||||
list.remove(i);
|
||||
if(selectedIndex == i)
|
||||
{
|
||||
updateSelection();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent removeIndex(int index)
|
||||
{
|
||||
if(list.remove(index) != null && selectedIndex == index)
|
||||
{
|
||||
updateSelection();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent removeIndexes(IntCollection values)
|
||||
{
|
||||
if(list.removeAll(values) && values.contains(selectedIndex))
|
||||
{
|
||||
updateSelection();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent setDefaultIndex(int index)
|
||||
{
|
||||
defaultIndex = index;
|
||||
if(index != -1 && selectedIndex == -1)
|
||||
{
|
||||
list.setSelectedIndex(index);
|
||||
updateSelection();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectionComponent setSelectedIndex(int index)
|
||||
{
|
||||
list.setSelectedIndex(index);
|
||||
updateSelection();
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getSelectedIndex()
|
||||
{
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
public String getSelectedValue()
|
||||
{
|
||||
return list.get(selectedIndex).getText();
|
||||
}
|
||||
|
||||
protected void createArrow()
|
||||
{
|
||||
if(buffer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
buffer.clear();
|
||||
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI).setOffset(-6F, -6F, 0F);
|
||||
tes.pos(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(0F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(0F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(6F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(6F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.pos(12F, 6F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
||||
tes.setOffset(0F, 0F, 0F);
|
||||
buffer.finishShape(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
if(animation != null)
|
||||
{
|
||||
animation.update(particalTicks);
|
||||
if(animation.isDone())
|
||||
{
|
||||
if(animation.get() < 1F)
|
||||
{
|
||||
isOpen = false;
|
||||
list.setVisible(false);
|
||||
}
|
||||
animation = null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brightness = getActiveBrightness();
|
||||
IGuiBox box = getBox();
|
||||
float minX = box.getMinX(10F);
|
||||
float minY = box.getMinY(10F);
|
||||
float currentZ = getRenderer().getCurrentZ();
|
||||
float rotation = animation != null ? animation.get() : (isOpen ? 90 : 0);
|
||||
UIRenderer render = getRenderer();
|
||||
render.setBrightness(brightness).drawQuad(box, color);
|
||||
render.setBrightness(brightness * 0.7F).drawQuad(box.getMinX(), box.getMinY(), box.getMinX(20F), box.getMaxY(), 0.001F, color);
|
||||
render.setFastTransform(false).setBrightness(brightness).translate(minX, minY, 0.02F + currentZ);
|
||||
render.scale(box.getScale()).rotateZ(rotation).drawBuffers(buffer, 0, 0).resetTransform().setFastTransform(true).translate(0F, 0F, 0.01F).setBrightness(1F);
|
||||
text.render(mouseX, mouseY, particalTicks);
|
||||
if(animation != null)
|
||||
{
|
||||
float progress = animation.get() / 90F;
|
||||
box = list.getBox();
|
||||
enableScissors(box.getMinX(), box.getMinY(), box.getWidth(), box.getHeight() * progress);
|
||||
list.render(mouseX, mouseY, particalTicks);
|
||||
disableScissors();
|
||||
}
|
||||
else if(isOpen)
|
||||
{
|
||||
list.render(mouseX, mouseY, particalTicks);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComponentColliding(int mouseX, int mouseY)
|
||||
{
|
||||
return isMouseOver(mouseX, mouseY) || (isOpen && list.isComponentColliding(mouseX, mouseY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidButton(int button)
|
||||
{
|
||||
return button == 0 || button == 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
//TODO look how to move into OnRelease
|
||||
if(isOpen && button == 0)
|
||||
{
|
||||
if(isMouseOver(mouseX, mouseY) && animation == null)
|
||||
{
|
||||
close();
|
||||
}
|
||||
return animation == null && list.onClick(button, mouseX, mouseY);
|
||||
}
|
||||
if(button == 2)
|
||||
{
|
||||
list.setSelectedIndex(-1);
|
||||
updateSelection();
|
||||
return true;
|
||||
}
|
||||
isOpen = true;
|
||||
list.setVisible(true);
|
||||
if(isAnimating())
|
||||
{
|
||||
animation = new LiniarValue(2F, 0F, 90F).setSmooth();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(int mouseX, int mouseY)
|
||||
{
|
||||
return isOpen && animation == null && list.onDrag(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
if(isOpen && animation == null)
|
||||
{
|
||||
list.onRelease(button, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(int scroll, int mouseX, int mouseY)
|
||||
{
|
||||
return isOpen && animation == null && list.onScroll(scroll, mouseX, mouseY);
|
||||
}
|
||||
|
||||
protected void close()
|
||||
{
|
||||
if(isAnimating())
|
||||
{
|
||||
animation = new LiniarValue(2F, 90F, 0F).setSmooth();
|
||||
}
|
||||
else
|
||||
{
|
||||
isOpen = false;
|
||||
list.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent t)
|
||||
{
|
||||
updateSelection();
|
||||
close();
|
||||
}
|
||||
|
||||
protected void updateSelection()
|
||||
{
|
||||
if(list.hasSelected())
|
||||
{
|
||||
selectedIndex = list.getSelectedIndex();
|
||||
text.setText(list.get(selectedIndex).getText());
|
||||
}
|
||||
else if(defaultIndex != -1)
|
||||
{
|
||||
list.setSelectedIndex(defaultIndex);
|
||||
selectedIndex = list.getSelectedIndex();
|
||||
text.setText(list.get(selectedIndex).getText());
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedIndex = -1;
|
||||
text.setText("Select Index");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,202 +1,213 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.math.misc.Facing;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
|
||||
public class SliderComponent extends GuiComponent implements IButtonComponent
|
||||
{
|
||||
TextComponent text = new TextComponent();
|
||||
protected int color;
|
||||
protected boolean vertical = false;
|
||||
|
||||
protected int min;
|
||||
protected int max;
|
||||
protected int value;
|
||||
int scrollEffect;
|
||||
IntFunction<String> textBuilder;
|
||||
protected RenderBuffer buffer;
|
||||
|
||||
public SliderComponent(int min, int max, int value, int color, IntFunction<String> textBuilder)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, min, max, value, color, textBuilder);
|
||||
}
|
||||
|
||||
public SliderComponent(float x, float y, float width, float height, int min, int max, int value, int color, IntFunction<String> textBuilder)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.value = MathUtils.clamp(min, max, value);
|
||||
this.color = color;
|
||||
this.textBuilder = textBuilder;
|
||||
updateText(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
text.setTextScale(0.35F);
|
||||
addChild(text, Constrains.parent());
|
||||
createArrow();
|
||||
}
|
||||
|
||||
protected void createArrow()
|
||||
{
|
||||
if(getGui() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(buffer == null)
|
||||
{
|
||||
addCloseListener(buffer = getRenderer().createBuffer());
|
||||
}
|
||||
buffer.clear();
|
||||
UIShapes.createArrow(buffer, 12F, 12F, color, vertical ? Facing.EAST : Facing.SOUTH);
|
||||
}
|
||||
|
||||
public TextComponent getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public SliderComponent updateText(boolean notifyListeners)
|
||||
{
|
||||
if(textBuilder != null)
|
||||
{
|
||||
text.setText(textBuilder.apply(value));
|
||||
}
|
||||
if(notifyListeners)
|
||||
{
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SliderComponent setColor(int color)
|
||||
{
|
||||
if(this.color != color)
|
||||
{
|
||||
this.color = color;
|
||||
createArrow();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SliderComponent setValue(int value)
|
||||
{
|
||||
int lastValue = this.value;
|
||||
this.value = MathUtils.clamp(min, max, value);
|
||||
if(lastValue != value)
|
||||
{
|
||||
updateText(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SliderComponent addValue(int value)
|
||||
{
|
||||
return setValue(this.value + value);
|
||||
}
|
||||
|
||||
public SliderComponent setScrollEffect(int scrollEffect)
|
||||
{
|
||||
this.scrollEffect = scrollEffect;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SliderComponent setVertical(boolean vertical)
|
||||
{
|
||||
if(this.vertical != vertical)
|
||||
{
|
||||
this.vertical = vertical;
|
||||
createArrow();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public float getPercentalValue()
|
||||
{
|
||||
return ((float)(value - min) / (float)(max - min));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brightness = getActiveBrightness();
|
||||
float minX = getBox().getMinX(5F);
|
||||
float minY = getBox().getMinY(2F);
|
||||
float maxX = getBox().getMaxX(-5F);
|
||||
float maxY = getBox().getMaxY(-2F);
|
||||
float scale = 0.6F * getBox().getScale();
|
||||
if(vertical)
|
||||
{
|
||||
float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxY(-3F) - getBox().getMinY(3F))) + getBox().getMinY(3F);
|
||||
float left = getBox().getMinX(2F);
|
||||
getRenderer().setBrightness(brightness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brightness * 0.7F).drawFrame(minX, minY, maxX, maxY, 0.001F, color);
|
||||
getRenderer().setBrightness(brightness * 0.5F).translate(left, extra, 0.002F).scale(scale).drawBuffers(buffer, maxX - minX, maxX - minX).setBrightness(brightness).unscale(scale).translate(-left, -extra, -0.002F);
|
||||
}
|
||||
else
|
||||
{
|
||||
float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxX(-6F) - getBox().getMinX(6F))) + getBox().getMinX(6F);
|
||||
float top = getBox().getMinY();
|
||||
getRenderer().setBrightness(brightness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brightness * 0.7F).drawFrame(minX, minY, maxX, maxY, 0.001F, color);
|
||||
getRenderer().setBrightness(brightness * 0.5F).translate(extra, top, 0.002F).scale(scale).drawBuffers(buffer, maxX - minX, maxX - minX).setBrightness(brightness).unscale(scale).translate(-extra, -top, -0.002F);
|
||||
}
|
||||
getRenderer().setBrightness(getBrightness(mouseX, mouseY));
|
||||
renderChildren(mouseX, mouseY, particalTicks);
|
||||
getRenderer().setBrightness(1F);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
updateScroll(mouseX, mouseY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(int mouseX, int mouseY)
|
||||
{
|
||||
updateScroll(mouseX, mouseY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(int scroll, int mouseX, int mouseY)
|
||||
{
|
||||
if(scrollEffect != 0)
|
||||
{
|
||||
int newValue = MathUtils.clamp(min, max, value + (scroll * scrollEffect));
|
||||
if(newValue != value)
|
||||
{
|
||||
value = newValue;
|
||||
updateText(true);
|
||||
}
|
||||
}
|
||||
return scrollEffect != 0;
|
||||
}
|
||||
|
||||
public void updateScroll(int mouseX, int mouseY)
|
||||
{
|
||||
float pos = vertical ? (mouseY - getBox().getMinY(2F)) / getBox().getHeight(-5F) : (mouseX - getBox().getMinX(5F)) / getBox().getWidth(-11F);
|
||||
int newValue = min + (int)(MathUtils.clamp(0F, 1F, pos) * (max - min));
|
||||
if(newValue != value)
|
||||
{
|
||||
value = newValue;
|
||||
updateText(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.math.misc.Facing;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
|
||||
public class SliderComponent extends GuiComponent implements IButtonComponent
|
||||
{
|
||||
TextComponent text = new TextComponent();
|
||||
protected int color;
|
||||
protected boolean vertical = false;
|
||||
|
||||
protected int min;
|
||||
protected int max;
|
||||
protected int value;
|
||||
int scrollEffect;
|
||||
IntFunction<String> textBuilder;
|
||||
protected RenderBuffer buffer;
|
||||
|
||||
public SliderComponent(int min, int max, int value, int color, IntFunction<String> textBuilder)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, min, max, value, color, 1F, textBuilder);
|
||||
}
|
||||
|
||||
public SliderComponent(int min, int max, int value, int color, float textScale, IntFunction<String> textBuilder)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, min, max, value, color, textScale, textBuilder);
|
||||
}
|
||||
|
||||
public SliderComponent(float x, float y, float width, float height, int min, int max, int value, int color, IntFunction<String> textBuilder)
|
||||
{
|
||||
this(x, y, width, height, min, max, value, color, 1F, textBuilder);
|
||||
}
|
||||
|
||||
public SliderComponent(float x, float y, float width, float height, int min, int max, int value, int color, float textScale, IntFunction<String> textBuilder)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.value = MathUtils.clamp(min, max, value);
|
||||
this.color = color;
|
||||
text.setTextScale(textScale);
|
||||
this.textBuilder = textBuilder;
|
||||
updateText(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
text.setTextScale(0.35F);
|
||||
addChild(text, Constrains.parent());
|
||||
createArrow();
|
||||
}
|
||||
|
||||
protected void createArrow()
|
||||
{
|
||||
if(getGui() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(buffer == null)
|
||||
{
|
||||
onClose(buffer = getRenderer().createBuffer());
|
||||
}
|
||||
buffer.clear();
|
||||
UIShapes.createArrow(buffer, 12F, 12F, color, vertical ? Facing.EAST : Facing.SOUTH);
|
||||
}
|
||||
|
||||
public TextComponent getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public SliderComponent updateText(boolean notifyListeners)
|
||||
{
|
||||
if(textBuilder != null)
|
||||
{
|
||||
text.setText(textBuilder.apply(value));
|
||||
}
|
||||
if(notifyListeners)
|
||||
{
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SliderComponent setColor(int color)
|
||||
{
|
||||
if(this.color != color)
|
||||
{
|
||||
this.color = color;
|
||||
createArrow();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SliderComponent setValue(int value)
|
||||
{
|
||||
int lastValue = this.value;
|
||||
this.value = MathUtils.clamp(min, max, value);
|
||||
if(lastValue != value)
|
||||
{
|
||||
updateText(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SliderComponent addValue(int value)
|
||||
{
|
||||
return setValue(this.value + value);
|
||||
}
|
||||
|
||||
public SliderComponent setScrollEffect(int scrollEffect)
|
||||
{
|
||||
this.scrollEffect = scrollEffect;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SliderComponent setVertical(boolean vertical)
|
||||
{
|
||||
if(this.vertical != vertical)
|
||||
{
|
||||
this.vertical = vertical;
|
||||
createArrow();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public float getPercentalValue()
|
||||
{
|
||||
return ((float)(value - min) / (float)(max - min));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brightness = getActiveBrightness();
|
||||
float minX = getBox().getMinX(5F);
|
||||
float minY = getBox().getMinY(2F);
|
||||
float maxX = getBox().getMaxX(-5F);
|
||||
float maxY = getBox().getMaxY(-2F);
|
||||
float scale = 0.6F * getBox().getScale();
|
||||
if(vertical)
|
||||
{
|
||||
float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxY(-3F) - getBox().getMinY(3F))) + getBox().getMinY(3F);
|
||||
float left = getBox().getMinX(2F);
|
||||
getRenderer().setBrightness(brightness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brightness * 0.7F).drawFrame(minX, minY, maxX, maxY, 0.001F, color);
|
||||
getRenderer().setBrightness(brightness * 0.5F).translate(left, extra, 0.002F).scale(scale).drawBuffers(buffer, maxX - minX, maxX - minX).setBrightness(brightness).unscale(scale).translate(-left, -extra, -0.002F);
|
||||
}
|
||||
else
|
||||
{
|
||||
float extra = (((float)(value - min) / (float)(max - min)) * (getBox().getMaxX(-6F) - getBox().getMinX(6F))) + getBox().getMinX(6F);
|
||||
float top = getBox().getMinY();
|
||||
getRenderer().setBrightness(brightness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brightness * 0.7F).drawFrame(minX, minY, maxX, maxY, 0.001F, color);
|
||||
getRenderer().setBrightness(brightness * 0.5F).translate(extra, top, 0.002F).scale(scale).drawBuffers(buffer, maxX - minX, maxX - minX).setBrightness(brightness).unscale(scale).translate(-extra, -top, -0.002F);
|
||||
}
|
||||
getRenderer().setBrightness(getBrightness(mouseX, mouseY));
|
||||
renderChildren(mouseX, mouseY, particalTicks);
|
||||
getRenderer().setBrightness(1F);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
updateScroll(mouseX, mouseY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(int mouseX, int mouseY)
|
||||
{
|
||||
updateScroll(mouseX, mouseY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(int scroll, int mouseX, int mouseY)
|
||||
{
|
||||
if(scrollEffect != 0)
|
||||
{
|
||||
int newValue = MathUtils.clamp(min, max, value + (scroll * scrollEffect));
|
||||
if(newValue != value)
|
||||
{
|
||||
value = newValue;
|
||||
updateText(true);
|
||||
}
|
||||
}
|
||||
return scrollEffect != 0;
|
||||
}
|
||||
|
||||
public void updateScroll(int mouseX, int mouseY)
|
||||
{
|
||||
float pos = vertical ? (mouseY - getBox().getMinY(2F)) / getBox().getHeight(-5F) : (mouseX - getBox().getMinX(5F)) / getBox().getWidth(-11F);
|
||||
int newValue = min + (int)(MathUtils.clamp(0F, 1F, pos) * (max - min));
|
||||
if(newValue != value)
|
||||
{
|
||||
value = newValue;
|
||||
updateText(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,437 +1,437 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.Align;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.FontRenderer;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.lexer.TextMetadata;
|
||||
|
||||
public class TextComponent extends GuiComponent
|
||||
{
|
||||
public static final int FLAG_STRIKE_THROUGH = 1 << 20;
|
||||
public static final int FLAG_UNDERLINE = 1 << 21;
|
||||
public static final int FLAG_BOLD = 1 << 22;
|
||||
public static final int FLAG_FORMATTING = 1 << 23;
|
||||
public static final int FLAG_FLIPPED = 1 << 24;
|
||||
public static final int FLAG_LIMITED_WIDTH = 1 << 25;
|
||||
public static final int FLAG_LIMITED_HEIGHT = 1 << 26;
|
||||
public static final int FLAG_AUTO_SCALE = 1 << 27;
|
||||
public static final int FLAG_SINGLE_LINE = 1 << 28;
|
||||
|
||||
FontRenderer font;
|
||||
String text = "";
|
||||
Align vertical = Align.CENTER;
|
||||
Align horizontal = Align.CENTER;
|
||||
int textColor = ColorUtils.WHITE;
|
||||
Integer backGroundColor = null;
|
||||
float italic = 0F;
|
||||
float textScale = 1F;
|
||||
RenderBuffer buffer;
|
||||
float initialSize;
|
||||
TextMetadata metadata = new TextMetadata(this);
|
||||
|
||||
public TextComponent()
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
|
||||
}
|
||||
|
||||
public TextComponent(String text)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, text);
|
||||
}
|
||||
|
||||
public TextComponent(float x, float y, float width, float height)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
|
||||
}
|
||||
|
||||
public TextComponent(float x, float y, float width, float height, String text)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
|
||||
setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addCloseListener(buffer = getRenderer().createBuffer());
|
||||
if(font == null)
|
||||
{
|
||||
setFont(getGui().getFont());
|
||||
}
|
||||
initialSize = getBox().getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
if(text.isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
float minX = getBox().getMinX();
|
||||
float minY = getBox().getMinY();
|
||||
getRenderer().translate(minX, minY).setActiveTexture(font.getTexture()).drawBuffers(buffer, getBox().getWidth(), getBox().getHeight()).translate(-minX, -minY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculateActualBounds(float[] area, boolean start)
|
||||
{
|
||||
if(start)
|
||||
{
|
||||
area[0] = Float.MAX_VALUE;
|
||||
area[1] = Float.MAX_VALUE;
|
||||
area[2] = Float.MIN_VALUE;
|
||||
area[3] = Float.MIN_VALUE;
|
||||
}
|
||||
IGuiBox box = getBox();
|
||||
area[0] = Math.min(area[0], box.getMinX() - metadata.getStartX());
|
||||
area[1] = Math.min(area[1], box.getMinY() - metadata.getStartY());
|
||||
area[2] = Math.max(area[2], (box.getMinX() - metadata.getStartX()) + metadata.getMaxWidth());
|
||||
area[3] = Math.max(area[3], (box.getMinY() - metadata.getStartY()) + metadata.getMaxHeight());
|
||||
for(GuiComponent comp : getChildren())
|
||||
{
|
||||
if(comp.isVisible()) comp.calculateActualBounds(area, false);
|
||||
}
|
||||
}
|
||||
|
||||
public RenderBuffer getBuffer()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repaint()
|
||||
{
|
||||
metadata.clear();
|
||||
if(font == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
font.updateText(this);
|
||||
}
|
||||
|
||||
public TextComponent setTextScale(float textScale)
|
||||
{
|
||||
if(this.textScale != textScale)
|
||||
{
|
||||
this.textScale = textScale;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextMetadata getMetadata()
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public final float getTextScale()
|
||||
{
|
||||
return textScale * getBox().getScale() * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F);
|
||||
}
|
||||
|
||||
public final float getRawTextScale()
|
||||
{
|
||||
return textScale * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F);
|
||||
}
|
||||
|
||||
public final float getWidth()
|
||||
{
|
||||
return getBox().getWidth() / getTextScale();
|
||||
}
|
||||
|
||||
public final float getItalic()
|
||||
{
|
||||
return italic;
|
||||
}
|
||||
|
||||
public final boolean isBold()
|
||||
{
|
||||
return isFlagSet(FLAG_BOLD);
|
||||
}
|
||||
|
||||
public final boolean isStrikeThrough()
|
||||
{
|
||||
return isFlagSet(FLAG_STRIKE_THROUGH);
|
||||
}
|
||||
|
||||
public final boolean isUnderlined()
|
||||
{
|
||||
return isFlagSet(FLAG_UNDERLINE);
|
||||
}
|
||||
|
||||
public final boolean isFlipped()
|
||||
{
|
||||
return isFlagSet(FLAG_FLIPPED);
|
||||
}
|
||||
|
||||
public final boolean isRenderingSpecial()
|
||||
{
|
||||
return isFlagSet(FLAG_FORMATTING);
|
||||
}
|
||||
|
||||
public final boolean isWidthLimited()
|
||||
{
|
||||
return isFlagSet(FLAG_LIMITED_WIDTH);
|
||||
}
|
||||
|
||||
public final boolean isHeightLimited()
|
||||
{
|
||||
return isFlagSet(FLAG_LIMITED_HEIGHT);
|
||||
}
|
||||
|
||||
public final boolean isLimitedText()
|
||||
{
|
||||
return isFlagSet(FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
|
||||
}
|
||||
|
||||
public final boolean isAutoScaling()
|
||||
{
|
||||
return isFlagSet(FLAG_AUTO_SCALE);
|
||||
}
|
||||
|
||||
public final boolean isForcedSingleLine()
|
||||
{
|
||||
return isFlagSet(FLAG_SINGLE_LINE);
|
||||
}
|
||||
|
||||
public final int getTextColor()
|
||||
{
|
||||
return textColor;
|
||||
}
|
||||
|
||||
public final Integer getBackgroundColor()
|
||||
{
|
||||
return backGroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontRenderer getFont()
|
||||
{
|
||||
return font;
|
||||
}
|
||||
|
||||
public String getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public String getText(int min)
|
||||
{
|
||||
return text.substring(min);
|
||||
}
|
||||
|
||||
public String getText(int min, int max)
|
||||
{
|
||||
return text.substring(min, max);
|
||||
}
|
||||
|
||||
public int length()
|
||||
{
|
||||
return text.length();
|
||||
}
|
||||
|
||||
public Align getVertical()
|
||||
{
|
||||
return vertical;
|
||||
}
|
||||
|
||||
public Align getHorizontal()
|
||||
{
|
||||
return horizontal;
|
||||
}
|
||||
|
||||
public final TextComponent bold(boolean value)
|
||||
{
|
||||
if(setFlag(FLAG_BOLD, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent strikethrough(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_STRIKE_THROUGH, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent underline(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_UNDERLINE, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent flipped(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_FLIPPED, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent special(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_FORMATTING, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent limit(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_LIMITED_HEIGHT | FLAG_LIMITED_WIDTH, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent limitWidth(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_LIMITED_WIDTH, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent limitHeight(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_LIMITED_HEIGHT, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent autoScale(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_AUTO_SCALE, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent singleLine(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_SINGLE_LINE, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent italic(boolean value)
|
||||
{
|
||||
return italic(value ? 3F : 0F);
|
||||
}
|
||||
|
||||
public final TextComponent italic(float value)
|
||||
{
|
||||
if(italic != value)
|
||||
{
|
||||
italic = value;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent align(Align horizontal, Align vertical)
|
||||
{
|
||||
if(this.horizontal != horizontal || this.vertical != vertical)
|
||||
{
|
||||
this.horizontal = horizontal;
|
||||
this.vertical = vertical;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent horizontal(Align horizontal)
|
||||
{
|
||||
if(this.horizontal != horizontal)
|
||||
{
|
||||
this.horizontal = horizontal;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent vertical(Align vertical)
|
||||
{
|
||||
if(this.vertical != vertical)
|
||||
{
|
||||
this.vertical = vertical;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent setText(String text)
|
||||
{
|
||||
if(text == null) text = "null";
|
||||
if(!this.text.equals(text))
|
||||
{
|
||||
this.text = text;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent textColor(int color)
|
||||
{
|
||||
if(textColor != color)
|
||||
{
|
||||
textColor = color;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent backgroundColor(int color)
|
||||
{
|
||||
if(backGroundColor != color)
|
||||
{
|
||||
backGroundColor = color;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent setFont(FontRenderer font)
|
||||
{
|
||||
if(this.font != font)
|
||||
{
|
||||
this.font = font;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.Align;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.FontRenderer;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.lexer.TextMetadata;
|
||||
|
||||
public class TextComponent extends GuiComponent
|
||||
{
|
||||
public static final int FLAG_STRIKE_THROUGH = 1 << 20;
|
||||
public static final int FLAG_UNDERLINE = 1 << 21;
|
||||
public static final int FLAG_BOLD = 1 << 22;
|
||||
public static final int FLAG_FORMATTING = 1 << 23;
|
||||
public static final int FLAG_FLIPPED = 1 << 24;
|
||||
public static final int FLAG_LIMITED_WIDTH = 1 << 25;
|
||||
public static final int FLAG_LIMITED_HEIGHT = 1 << 26;
|
||||
public static final int FLAG_AUTO_SCALE = 1 << 27;
|
||||
public static final int FLAG_SINGLE_LINE = 1 << 28;
|
||||
|
||||
FontRenderer font;
|
||||
String text = "";
|
||||
Align vertical = Align.CENTER;
|
||||
Align horizontal = Align.CENTER;
|
||||
int textColor = ColorUtils.WHITE;
|
||||
Integer backGroundColor = null;
|
||||
float italic = 0F;
|
||||
float textScale = 1F;
|
||||
RenderBuffer buffer;
|
||||
float initialSize;
|
||||
TextMetadata metadata = new TextMetadata(this);
|
||||
|
||||
public TextComponent()
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
|
||||
}
|
||||
|
||||
public TextComponent(String text)
|
||||
{
|
||||
this(0F, 0F, 0F, 0F, text);
|
||||
}
|
||||
|
||||
public TextComponent(float x, float y, float width, float height)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
|
||||
}
|
||||
|
||||
public TextComponent(float x, float y, float width, float height, String text)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
setFlag(FLAG_FORMATTING | FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
|
||||
setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
onClose(buffer = getRenderer().createBuffer());
|
||||
if(font == null)
|
||||
{
|
||||
setFont(getGui().getFont());
|
||||
}
|
||||
initialSize = getBox().getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
if(text.isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
float minX = getBox().getMinX();
|
||||
float minY = getBox().getMinY();
|
||||
getRenderer().translate(minX, minY).setActiveTexture(font.getTexture()).drawBuffers(buffer, getBox().getWidth(), getBox().getHeight()).translate(-minX, -minY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculateActualBounds(float[] area, boolean start)
|
||||
{
|
||||
if(start)
|
||||
{
|
||||
area[0] = Float.MAX_VALUE;
|
||||
area[1] = Float.MAX_VALUE;
|
||||
area[2] = Float.MIN_VALUE;
|
||||
area[3] = Float.MIN_VALUE;
|
||||
}
|
||||
IGuiBox box = getBox();
|
||||
area[0] = Math.min(area[0], box.getMinX() - metadata.getStartX());
|
||||
area[1] = Math.min(area[1], box.getMinY() - metadata.getStartY());
|
||||
area[2] = Math.max(area[2], (box.getMinX() - metadata.getStartX()) + metadata.getMaxWidth());
|
||||
area[3] = Math.max(area[3], (box.getMinY() - metadata.getStartY()) + metadata.getMaxHeight());
|
||||
for(GuiComponent comp : getChildren())
|
||||
{
|
||||
if(comp.isVisible()) comp.calculateActualBounds(area, false);
|
||||
}
|
||||
}
|
||||
|
||||
public RenderBuffer getBuffer()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repaint()
|
||||
{
|
||||
metadata.clear();
|
||||
if(font == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
font.updateText(this);
|
||||
}
|
||||
|
||||
public TextComponent setTextScale(float textScale)
|
||||
{
|
||||
if(this.textScale != textScale)
|
||||
{
|
||||
this.textScale = textScale;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextMetadata getMetadata()
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public final float getTextScale()
|
||||
{
|
||||
return textScale * getBox().getScale() * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F);
|
||||
}
|
||||
|
||||
public final float getRawTextScale()
|
||||
{
|
||||
return textScale * (isAutoScaling() ? getBox().getWidth() / initialSize : 1F);
|
||||
}
|
||||
|
||||
public final float getWidth()
|
||||
{
|
||||
return getBox().getWidth() / getTextScale();
|
||||
}
|
||||
|
||||
public final float getItalic()
|
||||
{
|
||||
return italic;
|
||||
}
|
||||
|
||||
public final boolean isBold()
|
||||
{
|
||||
return isFlagSet(FLAG_BOLD);
|
||||
}
|
||||
|
||||
public final boolean isStrikeThrough()
|
||||
{
|
||||
return isFlagSet(FLAG_STRIKE_THROUGH);
|
||||
}
|
||||
|
||||
public final boolean isUnderlined()
|
||||
{
|
||||
return isFlagSet(FLAG_UNDERLINE);
|
||||
}
|
||||
|
||||
public final boolean isFlipped()
|
||||
{
|
||||
return isFlagSet(FLAG_FLIPPED);
|
||||
}
|
||||
|
||||
public final boolean isRenderingSpecial()
|
||||
{
|
||||
return isFlagSet(FLAG_FORMATTING);
|
||||
}
|
||||
|
||||
public final boolean isWidthLimited()
|
||||
{
|
||||
return isFlagSet(FLAG_LIMITED_WIDTH);
|
||||
}
|
||||
|
||||
public final boolean isHeightLimited()
|
||||
{
|
||||
return isFlagSet(FLAG_LIMITED_HEIGHT);
|
||||
}
|
||||
|
||||
public final boolean isLimitedText()
|
||||
{
|
||||
return isFlagSet(FLAG_LIMITED_WIDTH | FLAG_LIMITED_HEIGHT);
|
||||
}
|
||||
|
||||
public final boolean isAutoScaling()
|
||||
{
|
||||
return isFlagSet(FLAG_AUTO_SCALE);
|
||||
}
|
||||
|
||||
public final boolean isForcedSingleLine()
|
||||
{
|
||||
return isFlagSet(FLAG_SINGLE_LINE);
|
||||
}
|
||||
|
||||
public final int getTextColor()
|
||||
{
|
||||
return textColor;
|
||||
}
|
||||
|
||||
public final Integer getBackgroundColor()
|
||||
{
|
||||
return backGroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontRenderer getFont()
|
||||
{
|
||||
return font;
|
||||
}
|
||||
|
||||
public String getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public String getText(int min)
|
||||
{
|
||||
return text.substring(min);
|
||||
}
|
||||
|
||||
public String getText(int min, int max)
|
||||
{
|
||||
return text.substring(min, max);
|
||||
}
|
||||
|
||||
public int length()
|
||||
{
|
||||
return text.length();
|
||||
}
|
||||
|
||||
public Align getVertical()
|
||||
{
|
||||
return vertical;
|
||||
}
|
||||
|
||||
public Align getHorizontal()
|
||||
{
|
||||
return horizontal;
|
||||
}
|
||||
|
||||
public final TextComponent bold(boolean value)
|
||||
{
|
||||
if(setFlag(FLAG_BOLD, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent strikethrough(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_STRIKE_THROUGH, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent underline(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_UNDERLINE, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent flipped(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_FLIPPED, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent special(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_FORMATTING, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent limit(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_LIMITED_HEIGHT | FLAG_LIMITED_WIDTH, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent limitWidth(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_LIMITED_WIDTH, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent limitHeight(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_LIMITED_HEIGHT, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent autoScale(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_AUTO_SCALE, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent singleLine(boolean value)
|
||||
{
|
||||
if(!setFlag(FLAG_SINGLE_LINE, value))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
onChanged(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final TextComponent italic(boolean value)
|
||||
{
|
||||
return italic(value ? 3F : 0F);
|
||||
}
|
||||
|
||||
public final TextComponent italic(float value)
|
||||
{
|
||||
if(italic != value)
|
||||
{
|
||||
italic = value;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent align(Align horizontal, Align vertical)
|
||||
{
|
||||
if(this.horizontal != horizontal || this.vertical != vertical)
|
||||
{
|
||||
this.horizontal = horizontal;
|
||||
this.vertical = vertical;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent horizontal(Align horizontal)
|
||||
{
|
||||
if(this.horizontal != horizontal)
|
||||
{
|
||||
this.horizontal = horizontal;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent vertical(Align vertical)
|
||||
{
|
||||
if(this.vertical != vertical)
|
||||
{
|
||||
this.vertical = vertical;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent setText(String text)
|
||||
{
|
||||
if(text == null) text = "null";
|
||||
if(!this.text.equals(text))
|
||||
{
|
||||
this.text = text;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent textColor(int color)
|
||||
{
|
||||
if(textColor != color)
|
||||
{
|
||||
textColor = color;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent backgroundColor(int color)
|
||||
{
|
||||
if(backGroundColor != color)
|
||||
{
|
||||
backGroundColor = color;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextComponent setFont(FontRenderer font)
|
||||
{
|
||||
if(this.font != font)
|
||||
{
|
||||
this.font = font;
|
||||
onChanged(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,356 +1,364 @@
|
|||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.ObjIntConsumer;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.math.misc.Facing;
|
||||
import speiger.src.coreengine.math.misc.FacingList;
|
||||
import speiger.src.coreengine.math.value.IValue;
|
||||
import speiger.src.coreengine.math.value.LiniarValue;
|
||||
import speiger.src.coreengine.math.vector.floats.Vec2f;
|
||||
import speiger.src.coreengine.math.vector.ints.Vec2i;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.icon.CrossIcon;
|
||||
import speiger.src.coreengine.rendering.gui.components.icon.LineIcon;
|
||||
import speiger.src.coreengine.rendering.gui.helper.Align;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.utils.Cursor;
|
||||
import speiger.src.coreengine.utils.functions.ConsumerConverter;
|
||||
import speiger.src.coreengine.utils.helpers.InternalThreadPools;
|
||||
|
||||
public class WindowComponent extends PanelComponent implements IButtonComponent, ObjIntConsumer<GuiComponent>
|
||||
{
|
||||
public static final Vec2f DEFAULT_MINIMUM_BOUNDS = Vec2f.of(75F, 7.5F);
|
||||
public static final int FLAG_MINIMIZED = 1 << 20;
|
||||
public static final int FLAG_RESIZEABLE = 1 << 21;
|
||||
public static final int FLAG_MOVEABLE = 1 << 22;
|
||||
public static final int FLAG_RESIZEABLE_HORIZONTAL = 1 << 23;
|
||||
public static final int FLAG_RESIZEABLE_VERTICAL = 1 << 24;
|
||||
public static final int FLAG_RESIZE_INVERT = 1 << 25;
|
||||
|
||||
public static final int WINDOW_FLAG_CLOSEABLE = 1;
|
||||
public static final int WINDOW_FLAG_MINIMIZEABLE = 2;
|
||||
|
||||
public static final int WINDOW_FLAGS = WINDOW_FLAG_CLOSEABLE | WINDOW_FLAG_MINIMIZEABLE;
|
||||
|
||||
public static final int DEFAULT_FLAGS = WINDOW_FLAGS | FLAG_RESIZEABLE | FLAG_MOVEABLE;
|
||||
public static final int FIXED_SIZE_WINDOW = WINDOW_FLAGS | FLAG_MOVEABLE;
|
||||
public static final int FIXED_SIZE_POPUP = WINDOW_FLAG_CLOSEABLE | FLAG_MOVEABLE;
|
||||
public static final int DYNAMIC_POPUP = FIXED_SIZE_POPUP | FLAG_RESIZEABLE;
|
||||
public static final int UNCLOSEABLE_WINDOW = WINDOW_FLAG_MINIMIZEABLE | FLAG_RESIZEABLE | FLAG_MOVEABLE;
|
||||
public static final int SUB_WINDOW = WINDOW_FLAG_MINIMIZEABLE | FLAG_RESIZEABLE | FLAG_RESIZE_INVERT;
|
||||
|
||||
final int flags;
|
||||
FacingList facing = null;
|
||||
String name;
|
||||
int color = ColorUtils.WINDOW_DEFAULT_BACKGROUND;
|
||||
Vec2f lastSize = Vec2f.mutable();
|
||||
Vec2i lastClick = Vec2i.mutable();
|
||||
IValue animation = null;
|
||||
protected final Consumer<GuiComponent> closeListener = new ConsumerConverter<GuiComponent>(0, this);
|
||||
protected final Consumer<GuiComponent> minimizedListener = new ConsumerConverter<GuiComponent>(2, this);
|
||||
|
||||
public WindowComponent(float x, float y, float width, float height, int flags, String name)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.name = name;
|
||||
this.flags = flags & WINDOW_FLAGS;
|
||||
setFlag(flags &= ~(WINDOW_FLAGS));
|
||||
setFlag(FLAG_RESIZEABLE_HORIZONTAL | FLAG_RESIZEABLE_VERTICAL);
|
||||
lastSize.set(getBox().getBaseWidth(), getBox().getBaseHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
LabelComponent label = new LabelComponent(name, ColorUtils.DARK_GRAY);
|
||||
label.getText().setTextScale(0.4F).horizontal(Align.LEFT_TOP).singleLine(true);
|
||||
addChild(label, new Constrains(null, null, new ParentConstrain(), new PixelConstrain(7.5F)));
|
||||
float offset = 9F;
|
||||
if((flags & WINDOW_FLAG_CLOSEABLE) != 0)
|
||||
{
|
||||
addChild(new IconButtonComponent(0F, 0F, 7.5F, 7.5F, ColorUtils.RED, new CrossIcon(ColorUtils.WHITE).setPadding(2.5F, 2F)).addUserActionListener(new ConsumerConverter<>(0, this)).setZOffset(0.001F), new Constrains(new PixelConstrain(offset).setInverted(), null, null, null));
|
||||
offset += 7.5F;
|
||||
}
|
||||
if((flags & WINDOW_FLAG_MINIMIZEABLE) != 0)
|
||||
{
|
||||
addChild(new IconButtonComponent(0F, 0F, 7.5F, 7.5F, ColorUtils.GRAY, new LineIcon(ColorUtils.WHITE, 0.7F, 0.25F)).addUserActionListener(new ConsumerConverter<>(1, this)).setZOffset(0.001F), new Constrains(new PixelConstrain(offset).setInverted(), null, null, null));
|
||||
}
|
||||
if(canMoveIntoForground())
|
||||
{
|
||||
setFlag(FLAG_RENDER_ORDER);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateMinizedState(boolean value)
|
||||
{
|
||||
if(setFlag(FLAG_MINIMIZED, value))
|
||||
{
|
||||
onChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
public final WindowComponent setMinimized(boolean value)
|
||||
{
|
||||
if((flags & WINDOW_FLAG_MINIMIZEABLE) != 0 && setFlag(FLAG_MINIMIZED, value))
|
||||
{
|
||||
if(value)
|
||||
{
|
||||
Vec2f last = InternalThreadPools.VEC2F.get().set(lastSize);
|
||||
bounds(last.getX(), isFlagSet(FLAG_MINIMIZED) ? getMinimizedY() : last.getY());
|
||||
lastSize.set(last);
|
||||
InternalThreadPools.VEC2F.accept(last.negate());
|
||||
}
|
||||
else bounds(lastSize.getX(), lastSize.getY());
|
||||
onChanged(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public final boolean isMinimized()
|
||||
{
|
||||
return isFlagSet(FLAG_MINIMIZED);
|
||||
}
|
||||
|
||||
public Vec2f getMinimumBounds()
|
||||
{
|
||||
return DEFAULT_MINIMUM_BOUNDS;
|
||||
}
|
||||
|
||||
public float getMinimizedY()
|
||||
{
|
||||
return 7.5F;
|
||||
}
|
||||
|
||||
public WindowComponent setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculateActualBounds(float[] area, boolean start)
|
||||
{
|
||||
if(animation != null)
|
||||
{
|
||||
float scale = getBox().getScale();
|
||||
area[0] = Math.min(area[0], getBox().getMinX());
|
||||
area[1] = Math.min(area[1], getBox().getMinY());
|
||||
area[2] = Math.max(area[2], lastSize.getX() * scale);
|
||||
area[3] = Math.max(area[3], animation.get(getMinimizedY(), lastSize.getY()) * scale);
|
||||
return;
|
||||
}
|
||||
super.calculateActualBounds(area, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState()
|
||||
{
|
||||
if(animation == null)
|
||||
{
|
||||
if(isFlagSet(FLAG_MINIMIZED))
|
||||
{
|
||||
lastSize.setX(getBox().getBaseWidth());
|
||||
return;
|
||||
}
|
||||
lastSize.set(getBox().getBaseWidth(), getBox().getBaseHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
if(animation != null)
|
||||
{
|
||||
animation.update(particalTicks);
|
||||
if(animation.isDone())
|
||||
{
|
||||
if(animation.get() < 0.1F)
|
||||
{
|
||||
updateMinizedState(true);
|
||||
}
|
||||
Vec2f last = InternalThreadPools.VEC2F.get().set(lastSize);
|
||||
bounds(last.getX(), isFlagSet(FLAG_MINIMIZED) ? getMinimizedY() : last.getY());
|
||||
lastSize.set(last);
|
||||
InternalThreadPools.VEC2F.accept(last.negate());
|
||||
animation = null;
|
||||
}
|
||||
notifyListeners(LISTENER_ON_CHANGE);
|
||||
}
|
||||
else if(isFlagSet(FLAG_RESIZEABLE) && !isOverChild(mouseX, mouseY) && !getGui().hasComponentInTheWay(getTopComponent(), mouseX, mouseY))
|
||||
{
|
||||
FacingList list = getBox().isColiding(mouseX, mouseY) ? getBox().getColidingBorder(mouseX, mouseY, 2F) : null;
|
||||
if(list != null)
|
||||
{
|
||||
if(isFlagNotSet(FLAG_RESIZEABLE_HORIZONTAL)) list = list.remove(FacingList.HORIZONTAL);
|
||||
if(isFlagNotSet(FLAG_RESIZEABLE_VERTICAL)) list = list.remove(FacingList.VERTICAL);
|
||||
bindCursor(list.containsAny(FacingList.VERTICAL) && isFlagNotSet(FLAG_MINIMIZED) ? Cursor.CURSOR_VRESIZE : (list.containsAny(FacingList.HORIZONTAL) ? Cursor.CURSOR_HRESIZE : null));
|
||||
}
|
||||
}
|
||||
if(isPopup() && !hasChildPopups() && !getGui().isComponentInFront(this))
|
||||
{
|
||||
requestFocus();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void preRender()
|
||||
{
|
||||
if(animation != null)
|
||||
{
|
||||
float scale = getBox().getScale();
|
||||
enableScissors(getBox().getMinX(), getBox().getMinY(), lastSize.getX() * scale, animation.get(getMinimizedY(), lastSize.getY()) * scale);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
getRenderer().drawQuad(getBox(), color);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postRender()
|
||||
{
|
||||
if(animation != null)
|
||||
{
|
||||
disableScissors();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent value, int index)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
getGui().removeComponent(this);
|
||||
break;
|
||||
case 1:
|
||||
if(animation != null || (flags & WINDOW_FLAG_MINIMIZEABLE) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
animation = (isMinimized() ? new LiniarValue(1F, 0F, 1F) : new LiniarValue(1F, 1F, 0F)).setSmooth();
|
||||
if(isMinimized())
|
||||
{
|
||||
bounds(lastSize.getX(), lastSize.getY());
|
||||
}
|
||||
updateMinizedState(false);
|
||||
break;
|
||||
case 2:
|
||||
value.setVisible(!isMinimized());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
if(isOverChild(mouseX, mouseY) || getGui().hasComponentInTheWay(getTopComponent(), mouseX, mouseY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
facing = getBox().getColidingBorder(mouseX, mouseY, 2F);
|
||||
lastClick.set(mouseX, mouseY);
|
||||
if(facing != null)
|
||||
{
|
||||
if(isFlagNotSet(FLAG_RESIZEABLE_HORIZONTAL)) facing = facing.remove(FacingList.HORIZONTAL);
|
||||
if(isFlagNotSet(FLAG_RESIZEABLE_VERTICAL)) facing = facing.remove(FacingList.VERTICAL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(int mouseX, int mouseY)
|
||||
{
|
||||
if(facing != null)
|
||||
{
|
||||
if(facing.isEmpty() && isFlagSet(FLAG_MOVEABLE))
|
||||
{
|
||||
move(mouseX - lastClick.getX(), mouseY - lastClick.getY());
|
||||
}
|
||||
else if(!facing.isEmpty() && isFlagSet(FLAG_RESIZEABLE))
|
||||
{
|
||||
float scale = getBox().getScale();
|
||||
float xChange = (mouseX - lastClick.getX()) * (facing.containsAny(FacingList.HORIZONTAL) ? 1F : 0F);
|
||||
float yChange = (mouseY - lastClick.getY()) * (facing.containsAny(FacingList.VERTICAL) ? 1F : 0F);
|
||||
if(isFlagSet(FLAG_RESIZE_INVERT))
|
||||
{
|
||||
xChange *= -1F;
|
||||
yChange *= -1F;
|
||||
}
|
||||
setMassChanging();
|
||||
if(facing.contains(Facing.NORTH) && isFlagNotSet(FLAG_MINIMIZED))
|
||||
{
|
||||
resize(0F, -(yChange / scale));
|
||||
move(0F, yChange);
|
||||
}
|
||||
else if(facing.contains(Facing.SOUTH) && isFlagNotSet(FLAG_MINIMIZED))
|
||||
{
|
||||
resize(0F, yChange / scale);
|
||||
}
|
||||
if(facing.contains(Facing.WEST))
|
||||
{
|
||||
resize(-(xChange / scale) - 1F, 0F);
|
||||
move(xChange, 0F);
|
||||
}
|
||||
else if(facing.contains(Facing.EAST))
|
||||
{
|
||||
resize(xChange / scale, 0F);
|
||||
}
|
||||
ensureMinimumBounds();
|
||||
finishMassChanging();
|
||||
if(xChange > 0F || yChange > 0F)
|
||||
{
|
||||
onChanged(true);
|
||||
}
|
||||
}
|
||||
lastClick.set(mouseX, mouseY);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
facing = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMoveIntoForground()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusLost()
|
||||
{
|
||||
facing = null;
|
||||
}
|
||||
|
||||
protected void ensureMinimumBounds()
|
||||
{
|
||||
IGuiBox box = getBox();
|
||||
Vec2f bounds = getMinimumBounds();
|
||||
if(box.getBaseWidth() < bounds.getX())
|
||||
{
|
||||
box.setWidth(bounds.getX());
|
||||
onChanged(true);
|
||||
}
|
||||
if(box.getBaseHeight() < bounds.getY())
|
||||
{
|
||||
box.setHeight(bounds.getY());
|
||||
onChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.ObjIntConsumer;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.math.misc.Facing;
|
||||
import speiger.src.coreengine.math.misc.FacingList;
|
||||
import speiger.src.coreengine.math.value.IValue;
|
||||
import speiger.src.coreengine.math.value.LiniarValue;
|
||||
import speiger.src.coreengine.math.vector.floats.Vec2f;
|
||||
import speiger.src.coreengine.math.vector.ints.Vec2i;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.icon.CrossIcon;
|
||||
import speiger.src.coreengine.rendering.gui.components.icon.LineIcon;
|
||||
import speiger.src.coreengine.rendering.gui.helper.Align;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.utils.Cursor;
|
||||
import speiger.src.coreengine.utils.functions.ConsumerConverter;
|
||||
import speiger.src.coreengine.utils.helpers.InternalThreadPools;
|
||||
import speiger.src.coreengine.utils.io.GameLog;
|
||||
|
||||
public class WindowComponent extends PanelComponent implements IButtonComponent, ObjIntConsumer<GuiComponent>
|
||||
{
|
||||
public static final Vec2f DEFAULT_MINIMUM_BOUNDS = Vec2f.of(75F, 7.5F);
|
||||
public static final int FLAG_MINIMIZED = 1 << 20;
|
||||
public static final int FLAG_RESIZEABLE = 1 << 21;
|
||||
public static final int FLAG_MOVEABLE = 1 << 22;
|
||||
public static final int FLAG_RESIZEABLE_HORIZONTAL = 1 << 23;
|
||||
public static final int FLAG_RESIZEABLE_VERTICAL = 1 << 24;
|
||||
public static final int FLAG_RESIZE_INVERT = 1 << 25;
|
||||
|
||||
public static final int WINDOW_FLAG_CLOSEABLE = 1;
|
||||
public static final int WINDOW_FLAG_MINIMIZEABLE = 2;
|
||||
|
||||
public static final int WINDOW_FLAGS = WINDOW_FLAG_CLOSEABLE | WINDOW_FLAG_MINIMIZEABLE;
|
||||
|
||||
public static final int DEFAULT_FLAGS = WINDOW_FLAGS | FLAG_RESIZEABLE | FLAG_MOVEABLE;
|
||||
public static final int FIXED_SIZE_WINDOW = WINDOW_FLAGS | FLAG_MOVEABLE;
|
||||
public static final int FIXED_SIZE_POPUP = WINDOW_FLAG_CLOSEABLE | FLAG_MOVEABLE;
|
||||
public static final int DYNAMIC_POPUP = FIXED_SIZE_POPUP | FLAG_RESIZEABLE;
|
||||
public static final int UNCLOSEABLE_WINDOW = WINDOW_FLAG_MINIMIZEABLE | FLAG_RESIZEABLE | FLAG_MOVEABLE;
|
||||
public static final int SUB_WINDOW = WINDOW_FLAG_MINIMIZEABLE | FLAG_RESIZEABLE | FLAG_RESIZE_INVERT;
|
||||
|
||||
final int flags;
|
||||
FacingList facing = null;
|
||||
String name;
|
||||
int color = ColorUtils.WINDOW_DEFAULT_BACKGROUND;
|
||||
Vec2f lastSize = Vec2f.mutable();
|
||||
Vec2i lastClick = Vec2i.mutable();
|
||||
IValue animation = null;
|
||||
protected final Consumer<GuiComponent> closeListener = new ConsumerConverter<GuiComponent>(0, this);
|
||||
protected final Consumer<GuiComponent> minimizedListener = new ConsumerConverter<GuiComponent>(2, this);
|
||||
|
||||
public WindowComponent(float x, float y, float width, float height, int flags, String name)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.name = name;
|
||||
this.flags = flags & WINDOW_FLAGS;
|
||||
setFlag(flags &= ~(WINDOW_FLAGS));
|
||||
setFlag(FLAG_RESIZEABLE_HORIZONTAL | FLAG_RESIZEABLE_VERTICAL);
|
||||
lastSize.set(getBox().getBaseWidth(), getBox().getBaseHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
LabelComponent label = new LabelComponent(name, ColorUtils.DARK_GRAY);
|
||||
label.getText().setTextScale(0.4F).horizontal(Align.LEFT_TOP).singleLine(true);
|
||||
addChild(label, new Constrains(null, null, new ParentConstrain(), new PixelConstrain(7.5F)));
|
||||
float offset = 9F;
|
||||
if((flags & WINDOW_FLAG_CLOSEABLE) != 0)
|
||||
{
|
||||
addChild(new IconButtonComponent(0F, 0F, 7.5F, 7.5F, ColorUtils.RED, new CrossIcon(ColorUtils.WHITE).setPadding(2.5F, 2F)).onAction(new ConsumerConverter<>(0, this)).setZOffset(0.001F), new Constrains(new PixelConstrain(offset).setInverted(), null, null, null));
|
||||
offset += 7.5F;
|
||||
}
|
||||
if((flags & WINDOW_FLAG_MINIMIZEABLE) != 0)
|
||||
{
|
||||
addChild(new IconButtonComponent(0F, 0F, 7.5F, 7.5F, ColorUtils.GRAY, new LineIcon(ColorUtils.WHITE, 0.7F, 0.25F)).onAction(new ConsumerConverter<>(1, this)).setZOffset(0.001F), new Constrains(new PixelConstrain(offset).setInverted(), null, null, null));
|
||||
}
|
||||
if(canMoveIntoForground())
|
||||
{
|
||||
setFlag(FLAG_RENDER_ORDER);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateMinizedState(boolean value)
|
||||
{
|
||||
if(setFlag(FLAG_MINIMIZED, value))
|
||||
{
|
||||
onChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
public final WindowComponent setMinimized(boolean value)
|
||||
{
|
||||
if((flags & WINDOW_FLAG_MINIMIZEABLE) != 0 && setFlag(FLAG_MINIMIZED, value))
|
||||
{
|
||||
if(value)
|
||||
{
|
||||
Vec2f last = InternalThreadPools.VEC2F.get().set(lastSize);
|
||||
bounds(last.getX(), isFlagSet(FLAG_MINIMIZED) ? getMinimizedY() : last.getY());
|
||||
lastSize.set(last);
|
||||
InternalThreadPools.VEC2F.accept(last.negate());
|
||||
}
|
||||
else bounds(lastSize.getX(), lastSize.getY());
|
||||
onChanged(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public final boolean isMinimized()
|
||||
{
|
||||
return isFlagSet(FLAG_MINIMIZED);
|
||||
}
|
||||
|
||||
public Vec2f getMinimumBounds()
|
||||
{
|
||||
return DEFAULT_MINIMUM_BOUNDS;
|
||||
}
|
||||
|
||||
public float getMinimizedY()
|
||||
{
|
||||
return 7.5F;
|
||||
}
|
||||
|
||||
public WindowComponent setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculateActualBounds(float[] area, boolean start)
|
||||
{
|
||||
if(animation != null)
|
||||
{
|
||||
float scale = getBox().getScale();
|
||||
area[0] = Math.min(area[0], getBox().getMinX());
|
||||
area[1] = Math.min(area[1], getBox().getMinY());
|
||||
area[2] = Math.max(area[2], lastSize.getX() * scale);
|
||||
area[3] = Math.max(area[3], animation.get(getMinimizedY(), lastSize.getY()) * scale);
|
||||
return;
|
||||
}
|
||||
super.calculateActualBounds(area, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState()
|
||||
{
|
||||
if(animation == null)
|
||||
{
|
||||
if(isFlagSet(FLAG_MINIMIZED))
|
||||
{
|
||||
lastSize.setX(getBox().getBaseWidth());
|
||||
return;
|
||||
}
|
||||
lastSize.set(getBox().getBaseWidth(), getBox().getBaseHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
if(animation != null)
|
||||
{
|
||||
animation.update(particalTicks);
|
||||
if(animation.isDone())
|
||||
{
|
||||
if(animation.get() < 0.1F)
|
||||
{
|
||||
updateMinizedState(true);
|
||||
}
|
||||
Vec2f last = InternalThreadPools.VEC2F.get().set(lastSize);
|
||||
bounds(last.getX(), isFlagSet(FLAG_MINIMIZED) ? getMinimizedY() : last.getY());
|
||||
lastSize.set(last);
|
||||
InternalThreadPools.VEC2F.accept(last.negate());
|
||||
animation = null;
|
||||
}
|
||||
notifyListeners(LISTENER_ON_CHANGE);
|
||||
}
|
||||
else if(isFlagSet(FLAG_RESIZEABLE) && !isOverChild(mouseX, mouseY) && !getGui().hasComponentInTheWay(getTopComponent(), mouseX, mouseY))
|
||||
{
|
||||
FacingList list = getBox().isColiding(mouseX, mouseY) ? getBox().getColidingBorder(mouseX, mouseY, 2F) : null;
|
||||
if(list != null)
|
||||
{
|
||||
if(isFlagNotSet(FLAG_RESIZEABLE_HORIZONTAL)) list = list.remove(FacingList.HORIZONTAL);
|
||||
if(isFlagNotSet(FLAG_RESIZEABLE_VERTICAL)) list = list.remove(FacingList.VERTICAL);
|
||||
bindCursor(list.containsAny(FacingList.VERTICAL) && isFlagNotSet(FLAG_MINIMIZED) ? Cursor.CURSOR_VRESIZE : (list.containsAny(FacingList.HORIZONTAL) ? Cursor.CURSOR_HRESIZE : null));
|
||||
}
|
||||
}
|
||||
if(isPopup() && !hasChildPopups() && !getGui().isComponentInFront(this))
|
||||
{
|
||||
requestFocus();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void preRender()
|
||||
{
|
||||
if(animation != null)
|
||||
{
|
||||
float scale = getBox().getScale();
|
||||
enableScissors(getBox().getMinX(), getBox().getMinY(), lastSize.getX() * scale, animation.get(getMinimizedY(), lastSize.getY()) * scale);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
getRenderer().drawQuad(getBox(), color);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postRender()
|
||||
{
|
||||
if(animation != null)
|
||||
{
|
||||
disableScissors();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent value, int index)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
getGui().removeComponent(this);
|
||||
break;
|
||||
case 1:
|
||||
if(animation != null || (flags & WINDOW_FLAG_MINIMIZEABLE) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
animation = (isMinimized() ? new LiniarValue(1F, 0F, 1F) : new LiniarValue(1F, 1F, 0F)).setSmooth();
|
||||
if(isMinimized())
|
||||
{
|
||||
bounds(lastSize.getX(), lastSize.getY());
|
||||
}
|
||||
updateMinizedState(false);
|
||||
break;
|
||||
case 2:
|
||||
value.setVisible(!isMinimized());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
if(getGui().hasComponentInTheWay(getTopComponent(), mouseX, mouseY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
facing = getBox().getColidingBorder(mouseX, mouseY, 2F);
|
||||
lastClick.set(mouseX, mouseY);
|
||||
if(facing != null)
|
||||
{
|
||||
GameLog.info("Testing: "+facing.getCode());
|
||||
if(isFlagNotSet(FLAG_RESIZEABLE_HORIZONTAL)) facing = facing.remove(FacingList.HORIZONTAL);
|
||||
if(isFlagNotSet(FLAG_RESIZEABLE_VERTICAL)) facing = facing.remove(FacingList.VERTICAL);
|
||||
if(isOverChild(mouseX, mouseY) && facing.isEmpty())
|
||||
{
|
||||
facing = null;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(int mouseX, int mouseY)
|
||||
{
|
||||
if(facing != null)
|
||||
{
|
||||
if(facing.isEmpty() && isFlagSet(FLAG_MOVEABLE))
|
||||
{
|
||||
move(mouseX - lastClick.getX(), mouseY - lastClick.getY());
|
||||
}
|
||||
else if(!facing.isEmpty() && isFlagSet(FLAG_RESIZEABLE))
|
||||
{
|
||||
float scale = getBox().getScale();
|
||||
float xChange = (mouseX - lastClick.getX()) * (facing.containsAny(FacingList.HORIZONTAL) ? 1F : 0F);
|
||||
float yChange = (mouseY - lastClick.getY()) * (facing.containsAny(FacingList.VERTICAL) ? 1F : 0F);
|
||||
if(isFlagSet(FLAG_RESIZE_INVERT))
|
||||
{
|
||||
xChange *= -1F;
|
||||
yChange *= -1F;
|
||||
}
|
||||
setMassChanging();
|
||||
if(facing.contains(Facing.NORTH) && isFlagNotSet(FLAG_MINIMIZED))
|
||||
{
|
||||
resize(0F, -(yChange / scale));
|
||||
move(0F, yChange);
|
||||
}
|
||||
else if(facing.contains(Facing.SOUTH) && isFlagNotSet(FLAG_MINIMIZED))
|
||||
{
|
||||
resize(0F, yChange / scale);
|
||||
}
|
||||
if(facing.contains(Facing.WEST))
|
||||
{
|
||||
resize(-(xChange / scale) - 1F, 0F);
|
||||
move(xChange, 0F);
|
||||
}
|
||||
else if(facing.contains(Facing.EAST))
|
||||
{
|
||||
resize(xChange / scale, 0F);
|
||||
}
|
||||
ensureMinimumBounds();
|
||||
finishMassChanging();
|
||||
if(xChange > 0F || yChange > 0F)
|
||||
{
|
||||
onChanged(true);
|
||||
}
|
||||
}
|
||||
lastClick.set(mouseX, mouseY);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
facing = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMoveIntoForground()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusLost()
|
||||
{
|
||||
facing = null;
|
||||
}
|
||||
|
||||
protected void ensureMinimumBounds()
|
||||
{
|
||||
IGuiBox box = getBox();
|
||||
Vec2f bounds = getMinimumBounds();
|
||||
if(box.getBaseWidth() < bounds.getX())
|
||||
{
|
||||
box.setWidth(bounds.getX());
|
||||
onChanged(true);
|
||||
}
|
||||
if(box.getBaseHeight() < bounds.getY())
|
||||
{
|
||||
box.setHeight(bounds.getY());
|
||||
onChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,84 +1,84 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.layouts;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
|
||||
public class VerticalLayout implements Consumer<GuiComponent>
|
||||
{
|
||||
GuiComponent parent;
|
||||
List<GuiComponent> components = new ObjectArrayList<>();
|
||||
IGuiBox box;
|
||||
float padding;
|
||||
boolean changing = false;
|
||||
|
||||
public VerticalLayout(List<GuiComponent> components, IGuiBox box, float padding)
|
||||
{
|
||||
this.components.addAll(components);
|
||||
for(int i = 0;i<components.size();i++)
|
||||
{
|
||||
components.get(i).addChangeListener(this).addCloseListener(this::removeComponent);
|
||||
}
|
||||
this.box = box;
|
||||
this.padding = padding;
|
||||
}
|
||||
|
||||
public VerticalLayout(IGuiBox box, float padding)
|
||||
{
|
||||
this.box = box;
|
||||
this.padding = padding;
|
||||
}
|
||||
|
||||
public void setParent(GuiComponent parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public <T extends GuiComponent> T addComponent(T gui)
|
||||
{
|
||||
components.add(gui);
|
||||
gui.addChangeListener(this);
|
||||
gui.addCloseListener(this::removeComponent);
|
||||
accept(null);
|
||||
return gui;
|
||||
}
|
||||
|
||||
public void removeComponent(GuiComponent gui)
|
||||
{
|
||||
if(components.remove(gui))
|
||||
{
|
||||
gui.removeChangeListener(this);
|
||||
gui.removeCloseListener(this::removeComponent);
|
||||
accept(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent t)
|
||||
{
|
||||
if(changing) return;
|
||||
changing = true;
|
||||
float minX = box.getBaseX();
|
||||
float minY = box.getBaseY();
|
||||
float currentY = 0F;
|
||||
for(int i = 0;i<components.size();i++)
|
||||
{
|
||||
GuiComponent component = components.get(i);
|
||||
component.setMassChanging();
|
||||
float[] bounds = new float[4];
|
||||
component.calculateActualBounds(bounds, true);
|
||||
float height = (bounds[3] - bounds[1]) + padding;
|
||||
component.set(minX, minY + currentY);
|
||||
currentY += height;
|
||||
component.finishMassChanging(true);
|
||||
}
|
||||
if(parent != null)
|
||||
{
|
||||
parent.onChanged(false);
|
||||
}
|
||||
changing = false;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.layouts;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
|
||||
public class VerticalLayout implements Consumer<GuiComponent>
|
||||
{
|
||||
GuiComponent parent;
|
||||
List<GuiComponent> components = new ObjectArrayList<>();
|
||||
IGuiBox box;
|
||||
float padding;
|
||||
boolean changing = false;
|
||||
|
||||
public VerticalLayout(List<GuiComponent> components, IGuiBox box, float padding)
|
||||
{
|
||||
this.components.addAll(components);
|
||||
for(int i = 0;i<components.size();i++)
|
||||
{
|
||||
components.get(i).onChange(this).onClose(this::removeComponent);
|
||||
}
|
||||
this.box = box;
|
||||
this.padding = padding;
|
||||
}
|
||||
|
||||
public VerticalLayout(IGuiBox box, float padding)
|
||||
{
|
||||
this.box = box;
|
||||
this.padding = padding;
|
||||
}
|
||||
|
||||
public void setParent(GuiComponent parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public <T extends GuiComponent> T addComponent(T gui)
|
||||
{
|
||||
components.add(gui);
|
||||
gui.onChange(this);
|
||||
gui.onClose(this::removeComponent);
|
||||
accept(null);
|
||||
return gui;
|
||||
}
|
||||
|
||||
public void removeComponent(GuiComponent gui)
|
||||
{
|
||||
if(components.remove(gui))
|
||||
{
|
||||
gui.removeChangeListener(this);
|
||||
gui.removeCloseListener(this::removeComponent);
|
||||
accept(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent t)
|
||||
{
|
||||
if(changing) return;
|
||||
changing = true;
|
||||
float minX = box.getBaseX();
|
||||
float minY = box.getBaseY();
|
||||
float currentY = 0F;
|
||||
for(int i = 0;i<components.size();i++)
|
||||
{
|
||||
GuiComponent component = components.get(i);
|
||||
component.setMassChanging();
|
||||
float[] bounds = new float[4];
|
||||
component.calculateActualBounds(bounds, true);
|
||||
float height = (bounds[3] - bounds[1]) + padding;
|
||||
component.set(minX, minY + currentY);
|
||||
currentY += height;
|
||||
component.finishMassChanging(true);
|
||||
}
|
||||
if(parent != null)
|
||||
{
|
||||
parent.onChanged(false);
|
||||
}
|
||||
changing = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,102 +1,102 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.menu;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.MenuConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
|
||||
public class MenuBarComponent extends GuiComponent
|
||||
{
|
||||
int color;
|
||||
List<MenuItemComponent> menuItems = new ObjectArrayList<MenuItemComponent>();
|
||||
float scale = 1F;
|
||||
|
||||
public MenuBarComponent(int color)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public MenuBarComponent(float x, float y, float width, float height, int color)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
}
|
||||
|
||||
public MenuBarComponent setTextScale(float scale)
|
||||
{
|
||||
if(this.scale != scale)
|
||||
{
|
||||
this.scale = scale;
|
||||
for(int i = 0,m=menuItems.size();i<m;i++)
|
||||
{
|
||||
menuItems.get(i).setTextScale(scale);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MenuItemComponent addMenuItem(String name)
|
||||
{
|
||||
return addMenuItem(new MenuItemComponent(name));
|
||||
}
|
||||
|
||||
public MenuItemComponent addText(String name)
|
||||
{
|
||||
return addMenuItem(new MenuTextComponent(name)).cast();
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent addCheckBox(String name)
|
||||
{
|
||||
return addMenuItem(new MenuCheckBoxComponent(name)).cast();
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent addCheckBox(String name, boolean defaultValue)
|
||||
{
|
||||
return addMenuItem(new MenuCheckBoxComponent(name, defaultValue)).cast();
|
||||
}
|
||||
|
||||
public MenuComponent addMenu(String name)
|
||||
{
|
||||
return addMenuItem(new MenuComponent(name)).addUserActionListener(this::closeMenus).cast();
|
||||
}
|
||||
|
||||
public MenuItemComponent addMenuItem(MenuItemComponent item)
|
||||
{
|
||||
menuItems.add(item);
|
||||
item.setMenuColor(color);
|
||||
addChild(item, new Constrains(new MenuConstrain<MenuItemComponent>(menuItems), new PixelConstrain(), item.createWidthConstriain(), new ParentConstrain()));
|
||||
item.setZOffset(0.3F);
|
||||
item.setTextScale(scale);
|
||||
item.onChanged(false);
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
getRenderer().drawQuad(getBox(), color);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void closeMenus(GuiComponent owner)
|
||||
{
|
||||
for(int i = 0,m=menuItems.size();i<m;i++)
|
||||
{
|
||||
MenuItemComponent comp = menuItems.get(i);
|
||||
if(comp != owner && comp instanceof MenuComponent)
|
||||
{
|
||||
((MenuComponent)comp).setOpen(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.menu;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.MenuConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
|
||||
public class MenuBarComponent extends GuiComponent
|
||||
{
|
||||
int color;
|
||||
List<MenuItemComponent> menuItems = new ObjectArrayList<MenuItemComponent>();
|
||||
float scale = 1F;
|
||||
|
||||
public MenuBarComponent(int color)
|
||||
{
|
||||
super(0F, 0F, 0F, 0F);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public MenuBarComponent(float x, float y, float width, float height, int color)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
}
|
||||
|
||||
public MenuBarComponent setTextScale(float scale)
|
||||
{
|
||||
if(this.scale != scale)
|
||||
{
|
||||
this.scale = scale;
|
||||
for(int i = 0,m=menuItems.size();i<m;i++)
|
||||
{
|
||||
menuItems.get(i).setTextScale(scale);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MenuItemComponent addMenuItem(String name)
|
||||
{
|
||||
return addMenuItem(new MenuItemComponent(name));
|
||||
}
|
||||
|
||||
public MenuItemComponent addText(String name)
|
||||
{
|
||||
return addMenuItem(new MenuTextComponent(name)).cast();
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent addCheckBox(String name)
|
||||
{
|
||||
return addMenuItem(new MenuCheckBoxComponent(name)).cast();
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent addCheckBox(String name, boolean defaultValue)
|
||||
{
|
||||
return addMenuItem(new MenuCheckBoxComponent(name, defaultValue)).cast();
|
||||
}
|
||||
|
||||
public MenuComponent addMenu(String name)
|
||||
{
|
||||
return addMenuItem(new MenuComponent(name)).onAction(this::closeMenus).cast();
|
||||
}
|
||||
|
||||
public MenuItemComponent addMenuItem(MenuItemComponent item)
|
||||
{
|
||||
menuItems.add(item);
|
||||
item.setMenuColor(color);
|
||||
addChild(item, new Constrains(new MenuConstrain<MenuItemComponent>(menuItems), new PixelConstrain(), item.createWidthConstriain(), new ParentConstrain()));
|
||||
item.setZOffset(0.3F);
|
||||
item.setTextScale(scale);
|
||||
item.onChanged(false);
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
getRenderer().drawQuad(getBox(), color);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void closeMenus(GuiComponent owner)
|
||||
{
|
||||
for(int i = 0,m=menuItems.size();i<m;i++)
|
||||
{
|
||||
MenuItemComponent comp = menuItems.get(i);
|
||||
if(comp != owner && comp instanceof MenuComponent)
|
||||
{
|
||||
((MenuComponent)comp).setOpen(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,126 +1,126 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.menu;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.components.misc.ICheckBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
|
||||
public class MenuCheckBoxComponent extends MenuItemComponent implements ICheckBox<MenuCheckBoxComponent>
|
||||
{
|
||||
public static final int FLAG_CHECKED = 1 << 21;
|
||||
RenderBuffer buffer;
|
||||
|
||||
public MenuCheckBoxComponent(String name)
|
||||
{
|
||||
super(name);
|
||||
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent(String name, boolean checked)
|
||||
{
|
||||
super(name);
|
||||
setFlag(FLAG_CHECKED, checked);
|
||||
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent(float x, float y, float width, float height, String name)
|
||||
{
|
||||
super(x, y, width, height, name);
|
||||
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent(float x, float y, float width, float height, String name, boolean checked)
|
||||
{
|
||||
super(x, y, width, height, name);
|
||||
setFlag(FLAG_CHECKED, checked);
|
||||
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addChild(text, new Constrains(new PixelConstrain(getBox().getHeight() + 1F), new ParentConstrain(), new DynamicConstrain(() -> text.getMetadata().getMaxWidth() + 0.5F), new ParentConstrain()));
|
||||
addCloseListener(buffer = getRenderer().createBuffer());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repaint()
|
||||
{
|
||||
float width = getBox().getHeight();
|
||||
float height = getBox().getHeight();
|
||||
buffer.clear();
|
||||
UIShapes.createCross(buffer, width, height, (width / 3.3F), (height / 5F), color);
|
||||
UIShapes.createCross(buffer, width, height, (width / 5F), (height / 10F), color);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Constrain createWidthConstriain()
|
||||
{
|
||||
return new DynamicConstrain(() -> text.getMetadata().getMaxWidth() + getBox().getHeight() + 3F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isChecked()
|
||||
{
|
||||
return isFlagSet(FLAG_CHECKED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MenuCheckBoxComponent setChecked(boolean value)
|
||||
{
|
||||
setFlag(FLAG_CHECKED, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brightness = getActiveBrightness();
|
||||
float height = getBox().getHeight();
|
||||
float centerX = getBox().getMinX(height * 0.5F);
|
||||
float centerY = getBox().getMinY(height * 0.5F);
|
||||
getRenderer().setBrightness(brightness * 0.85F).drawQuad(getBox().getMinX(0.2F), getBox().getMinY(), getBox().getMinX(height + 0.2F), getBox().getMinY(height), color).setBrightness(brightness * 0.75F).drawFrame(getBox().getMinX(0.2F), getBox().getMinY(), getBox().getMinX(height + 0.2F), getBox().getMinY(height), color).translate(centerX, centerY);
|
||||
if(isChecked())
|
||||
{
|
||||
getRenderer().setBrightness(brightness * 0.7F).translate(0, 0, 0.001F).drawBuffers(buffer.selectionIterator(1), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.001F);
|
||||
}
|
||||
if(isHovered(mouseX, mouseY))
|
||||
{
|
||||
getRenderer().setBrightness(brightness * 1.3F).translate(0, 0, 0.002F).drawBuffers(buffer.selectionIterator(0), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.002F);
|
||||
}
|
||||
float maxX = Math.min(boxWidth, getBox().getMaxX());
|
||||
getRenderer().setBrightness(1F).translate(-centerX, -centerY).drawQuad(getBox().getMinX(height), getBox().getMinY(), getBox().getMinX(maxX), getBox().getMaxY(), color).setBrightness(brightness * 0.75F).drawFrame(getBox().getMinX(height), getBox().getMinY(), getBox().getMinX(maxX), getBox().getMaxY(), color);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isCheckBoxHovered(int mouseX, int mouseY)
|
||||
{
|
||||
float height = getBox().getHeight();
|
||||
return getBox().getMinX() <= mouseX && getBox().getMinX(height) >= mouseX && getBox().getMinY() <= mouseY && getBox().getMinY(height) >= mouseY && getGui().hasComponentInTheWay(this, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
setFlag(FLAG_CHECKED, !isFlagSet(FLAG_CHECKED));
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onUserKey()
|
||||
{
|
||||
setFlag(FLAG_CHECKED, !isFlagSet(FLAG_CHECKED));
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.menu;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.components.misc.ICheckBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.UIShapes;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
||||
|
||||
public class MenuCheckBoxComponent extends MenuItemComponent implements ICheckBox<MenuCheckBoxComponent>
|
||||
{
|
||||
public static final int FLAG_CHECKED = 1 << 21;
|
||||
RenderBuffer buffer;
|
||||
|
||||
public MenuCheckBoxComponent(String name)
|
||||
{
|
||||
super(name);
|
||||
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent(String name, boolean checked)
|
||||
{
|
||||
super(name);
|
||||
setFlag(FLAG_CHECKED, checked);
|
||||
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent(float x, float y, float width, float height, String name)
|
||||
{
|
||||
super(x, y, width, height, name);
|
||||
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent(float x, float y, float width, float height, String name, boolean checked)
|
||||
{
|
||||
super(x, y, width, height, name);
|
||||
setFlag(FLAG_CHECKED, checked);
|
||||
setFlag(FLAG_KEEP_MENU_OPEN | FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
addChild(text, new Constrains(new PixelConstrain(getBox().getHeight() + 1F), new ParentConstrain(), new DynamicConstrain(() -> text.getMetadata().getMaxWidth() + 0.5F), new ParentConstrain()));
|
||||
onClose(buffer = getRenderer().createBuffer());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repaint()
|
||||
{
|
||||
float width = getBox().getHeight();
|
||||
float height = getBox().getHeight();
|
||||
buffer.clear();
|
||||
UIShapes.createCross(buffer, width, height, (width / 3.3F), (height / 5F), color);
|
||||
UIShapes.createCross(buffer, width, height, (width / 5F), (height / 10F), color);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Constrain createWidthConstriain()
|
||||
{
|
||||
return new DynamicConstrain(() -> text.getMetadata().getMaxWidth() + getBox().getHeight() + 3F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isChecked()
|
||||
{
|
||||
return isFlagSet(FLAG_CHECKED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MenuCheckBoxComponent setChecked(boolean value)
|
||||
{
|
||||
setFlag(FLAG_CHECKED, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brightness = getActiveBrightness();
|
||||
float height = getBox().getHeight();
|
||||
float centerX = getBox().getMinX(height * 0.5F);
|
||||
float centerY = getBox().getMinY(height * 0.5F);
|
||||
getRenderer().setBrightness(brightness * 0.85F).drawQuad(getBox().getMinX(0.2F), getBox().getMinY(), getBox().getMinX(height + 0.2F), getBox().getMinY(height), color).setBrightness(brightness * 0.75F).drawFrame(getBox().getMinX(0.2F), getBox().getMinY(), getBox().getMinX(height + 0.2F), getBox().getMinY(height), color).translate(centerX, centerY);
|
||||
if(isChecked())
|
||||
{
|
||||
getRenderer().setBrightness(brightness * 0.7F).translate(0, 0, 0.001F).drawBuffers(buffer.selectionIterator(1), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.001F);
|
||||
}
|
||||
if(isHovered(mouseX, mouseY))
|
||||
{
|
||||
getRenderer().setBrightness(brightness * 1.3F).translate(0, 0, 0.002F).drawBuffers(buffer.selectionIterator(0), getBox().getWidth(), getBox().getHeight()).translate(0, 0, -0.002F);
|
||||
}
|
||||
float maxX = Math.min(boxWidth, getBox().getMaxX());
|
||||
getRenderer().setBrightness(1F).translate(-centerX, -centerY).drawQuad(getBox().getMinX(height), getBox().getMinY(), getBox().getMinX(maxX), getBox().getMaxY(), color).setBrightness(brightness * 0.75F).drawFrame(getBox().getMinX(height), getBox().getMinY(), getBox().getMinX(maxX), getBox().getMaxY(), color);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isCheckBoxHovered(int mouseX, int mouseY)
|
||||
{
|
||||
float height = getBox().getHeight();
|
||||
return getBox().getMinX() <= mouseX && getBox().getMinX(height) >= mouseX && getBox().getMinY() <= mouseY && getBox().getMinY(height) >= mouseY && getGui().hasComponentInTheWay(this, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(int button, int mouseX, int mouseY)
|
||||
{
|
||||
setFlag(FLAG_CHECKED, !isFlagSet(FLAG_CHECKED));
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onUserKey()
|
||||
{
|
||||
setFlag(FLAG_CHECKED, !isFlagSet(FLAG_CHECKED));
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,318 +1,318 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.menu;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.MenuConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
|
||||
public class MenuComponent extends MenuItemComponent implements Consumer<GuiComponent>
|
||||
{
|
||||
static final int FLAG_OPEN = 1 << 21;
|
||||
static final int FLAG_SUB_MENU = 1 << 22;
|
||||
List<MenuItemComponent> components = new ObjectArrayList<MenuItemComponent>();
|
||||
float defaultScale = 1F;
|
||||
float width = 0F;
|
||||
float entryHeight = 10F;
|
||||
float textScale = 1F;
|
||||
long timeNotHovered = -1;
|
||||
MenuComponent ownerMenu;
|
||||
|
||||
public MenuComponent(String name)
|
||||
{
|
||||
super(name);
|
||||
clearFlag(FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
public MenuComponent(float x, float y, float width, float height, String name)
|
||||
{
|
||||
super(x, y, width, height, name);
|
||||
clearFlag(FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMoveIntoForground()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public MenuComponent setHeight(float height)
|
||||
{
|
||||
entryHeight = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected MenuComponent setParent(MenuComponent owner)
|
||||
{
|
||||
ownerMenu = owner;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setMenuColor(int color)
|
||||
{
|
||||
super.setMenuColor(color);
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
components.get(i).setMenuColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuComponent setDefaultScale(float scale)
|
||||
{
|
||||
defaultScale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setTextScale(float scale)
|
||||
{
|
||||
super.setTextScale(scale);
|
||||
if(textScale != scale)
|
||||
{
|
||||
textScale = scale;
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
components.get(i).setTextScale(textScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setBoxWidth(float value)
|
||||
{
|
||||
boolean changed = boxWidth != value;
|
||||
super.setBoxWidth(value);
|
||||
if(changed)
|
||||
{
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
components.get(i).onChanged(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MenuComponent addSubMenu(String name)
|
||||
{
|
||||
return addMenuItem(new MenuComponent(name+" >").setIsSubMenu(true).setParent(this)).cast();
|
||||
}
|
||||
|
||||
public MenuItemComponent addText(String name)
|
||||
{
|
||||
return addMenuItem(new MenuTextComponent(name)).cast();
|
||||
}
|
||||
|
||||
public MenuItemComponent addMenuItem(String name)
|
||||
{
|
||||
return addMenuItem(new MenuItemComponent(name));
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent addCheckBox(String name)
|
||||
{
|
||||
return addMenuItem(new MenuCheckBoxComponent(name)).cast();
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent addCheckBox(String name, boolean value)
|
||||
{
|
||||
return addMenuItem(new MenuCheckBoxComponent(name, value)).cast();
|
||||
}
|
||||
|
||||
public MenuItemComponent addMenuItem(MenuItemComponent comp)
|
||||
{
|
||||
components.add(comp);
|
||||
comp.setScale(defaultScale);
|
||||
comp.setMenuColor(color);
|
||||
addChild(comp.setIgnoreBounds(true).addUserActionListener(this), createConstrains(comp)).onChanged(false);
|
||||
comp.setVisible(isFlagSet(FLAG_OPEN));
|
||||
comp.setTextScale(textScale);
|
||||
return comp;
|
||||
}
|
||||
|
||||
protected Constrains createConstrains(MenuItemComponent comp)
|
||||
{
|
||||
Constrain constraint = isFlagSet(FLAG_SUB_MENU) ? new DynamicConstrain(() -> Math.max(getBox().getBaseWidth(), boxWidth / getBox().getScale())) : new PixelConstrain();
|
||||
return new Constrains(constraint, new MenuConstrain<MenuItemComponent>(components, isFlagSet(FLAG_SUB_MENU) ? MenuConstrain.DEFAULT : () -> getBox().getBaseHeight() + 0.1F).setPadding(0.01F), comp.createWidthConstriain(), new PixelConstrain(entryHeight));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuiComponent removeChild(GuiComponent comp)
|
||||
{
|
||||
super.removeChild(comp);
|
||||
if(components.remove(comp))
|
||||
{
|
||||
onChanged(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuiComponent removeChildren()
|
||||
{
|
||||
components.clear();
|
||||
return super.removeChildren();
|
||||
}
|
||||
|
||||
public void removeElements()
|
||||
{
|
||||
for(MenuItemComponent comp : components)
|
||||
{
|
||||
super.removeChild(comp);
|
||||
}
|
||||
components.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
if(isSubMenu() && isVisible())
|
||||
{
|
||||
if(isFlagSet(FLAG_OPEN))
|
||||
{
|
||||
if(isMouseOver(mouseX, mouseY) || isOverChild(mouseX, mouseY))
|
||||
{
|
||||
timeNotHovered = -1;
|
||||
return true;
|
||||
}
|
||||
if(timeNotHovered == -1)
|
||||
{
|
||||
timeNotHovered = getGlobalClock();
|
||||
}
|
||||
if(getGlobalClock() - timeNotHovered > 10)
|
||||
{
|
||||
setOpen(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
timeNotHovered = -1;
|
||||
if(isMouseOver(mouseX, mouseY) && !ownerMenu.hasOtherMenuOpen(this))
|
||||
{
|
||||
setOpen(true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brigthness = isFlagSet(FLAG_OPEN) ? 0.7F : getBrightness(mouseX, mouseY);
|
||||
float minX = getBox().getMinX(0.2F);
|
||||
float minY = getBox().getMinY(0.2F);
|
||||
float maxX = Math.max(getBox().getMaxX(), minX + boxWidth);
|
||||
float maxY = getBox().getMaxY(-0.2F);
|
||||
getRenderer().setBrightness(brigthness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brigthness * 0.5F).drawFrame(minX, minY, maxX, maxY, color);
|
||||
text.setBrightness(brigthness);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
if(!isSubMenu())
|
||||
{
|
||||
setOpen(!isFlagSet(FLAG_OPEN)).notifyListeners(LISTENER_USER_ACTION);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected MenuComponent setIsSubMenu(boolean value)
|
||||
{
|
||||
if(setFlag(FLAG_SUB_MENU, value))
|
||||
{
|
||||
setFlag(FLAG_KEEP_MENU_OPEN, value);
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
MenuItemComponent comp = components.get(i);
|
||||
addConstrains(comp, createConstrains(comp));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isSubMenu()
|
||||
{
|
||||
return isFlagSet(FLAG_SUB_MENU);
|
||||
}
|
||||
|
||||
public MenuComponent setOpen(boolean open)
|
||||
{
|
||||
if(setFlag(FLAG_OPEN, open))
|
||||
{
|
||||
width = 0F;
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
GuiComponent comp = components.get(i);
|
||||
comp.setVisible(open);
|
||||
width = Math.max(width, comp.getBox().getBaseWidth());
|
||||
}
|
||||
width *= getBox().getScale();
|
||||
width += 1F;
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
components.get(i).setBoxWidth(width);
|
||||
}
|
||||
onChanged(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
protected boolean hasOtherMenuOpen(MenuComponent other)
|
||||
{
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
MenuItemComponent comp = components.get(i);
|
||||
if(comp != other && comp instanceof MenuComponent && comp.isFlagSet(FLAG_OPEN))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState()
|
||||
{
|
||||
if(isFlagSet(FLAG_OPEN) != isVisible())
|
||||
{
|
||||
boolean isOpen = isFlagSet(FLAG_OPEN);
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
components.get(i).setVisible(isOpen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusLost()
|
||||
{
|
||||
if(!isChildFocused())
|
||||
{
|
||||
setOpen(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent t)
|
||||
{
|
||||
if(t.cast(MenuItemComponent.class).isNotClosingMenu())
|
||||
{
|
||||
return;
|
||||
}
|
||||
setOpen(false);
|
||||
if(ownerMenu != null)
|
||||
{
|
||||
ownerMenu.accept(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Menu: "+getText().getText();
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.menu;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.MenuConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
|
||||
public class MenuComponent extends MenuItemComponent implements Consumer<GuiComponent>
|
||||
{
|
||||
static final int FLAG_OPEN = 1 << 21;
|
||||
static final int FLAG_SUB_MENU = 1 << 22;
|
||||
List<MenuItemComponent> components = new ObjectArrayList<>();
|
||||
float defaultScale = 1F;
|
||||
float width = 0F;
|
||||
float entryHeight = 10F;
|
||||
float textScale = 1F;
|
||||
long timeNotHovered = -1;
|
||||
MenuComponent ownerMenu;
|
||||
|
||||
public MenuComponent(String name)
|
||||
{
|
||||
super(name);
|
||||
clearFlag(FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
public MenuComponent(float x, float y, float width, float height, String name)
|
||||
{
|
||||
super(x, y, width, height, name);
|
||||
clearFlag(FLAG_SUPPORT_BINDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMoveIntoForground()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public MenuComponent setHeight(float height)
|
||||
{
|
||||
entryHeight = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected MenuComponent setParent(MenuComponent owner)
|
||||
{
|
||||
ownerMenu = owner;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setMenuColor(int color)
|
||||
{
|
||||
super.setMenuColor(color);
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
components.get(i).setMenuColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuComponent setDefaultScale(float scale)
|
||||
{
|
||||
defaultScale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setTextScale(float scale)
|
||||
{
|
||||
super.setTextScale(scale);
|
||||
if(textScale != scale)
|
||||
{
|
||||
textScale = scale;
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
components.get(i).setTextScale(textScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setBoxWidth(float value)
|
||||
{
|
||||
boolean changed = boxWidth != value;
|
||||
super.setBoxWidth(value);
|
||||
if(changed)
|
||||
{
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
components.get(i).onChanged(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MenuComponent addSubMenu(String name)
|
||||
{
|
||||
return addMenuItem(new MenuComponent(name+" >").setIsSubMenu(true).setParent(this)).cast();
|
||||
}
|
||||
|
||||
public MenuItemComponent addText(String name)
|
||||
{
|
||||
return addMenuItem(new MenuTextComponent(name)).cast();
|
||||
}
|
||||
|
||||
public MenuItemComponent addMenuItem(String name)
|
||||
{
|
||||
return addMenuItem(new MenuItemComponent(name));
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent addCheckBox(String name)
|
||||
{
|
||||
return addMenuItem(new MenuCheckBoxComponent(name)).cast();
|
||||
}
|
||||
|
||||
public MenuCheckBoxComponent addCheckBox(String name, boolean value)
|
||||
{
|
||||
return addMenuItem(new MenuCheckBoxComponent(name, value)).cast();
|
||||
}
|
||||
|
||||
public MenuItemComponent addMenuItem(MenuItemComponent comp)
|
||||
{
|
||||
components.add(comp);
|
||||
comp.setScale(defaultScale);
|
||||
comp.setMenuColor(color);
|
||||
addChild(comp.setIgnoreBounds(true).onAction(this), createConstrains(comp)).onChanged(false);
|
||||
comp.setVisible(isFlagSet(FLAG_OPEN));
|
||||
comp.setTextScale(textScale);
|
||||
return comp;
|
||||
}
|
||||
|
||||
protected Constrains createConstrains(MenuItemComponent comp)
|
||||
{
|
||||
Constrain constraint = isFlagSet(FLAG_SUB_MENU) ? new DynamicConstrain(() -> Math.max(getBox().getBaseWidth(), boxWidth / getBox().getScale())) : new PixelConstrain();
|
||||
return new Constrains(constraint, new MenuConstrain<MenuItemComponent>(components, isFlagSet(FLAG_SUB_MENU) ? MenuConstrain.DEFAULT : () -> getBox().getBaseHeight() + 0.1F).setPadding(0.01F), comp.createWidthConstriain(), new PixelConstrain(entryHeight));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuiComponent removeChild(GuiComponent comp)
|
||||
{
|
||||
super.removeChild(comp);
|
||||
if(components.remove(comp))
|
||||
{
|
||||
onChanged(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuiComponent removeChildren()
|
||||
{
|
||||
components.clear();
|
||||
return super.removeChildren();
|
||||
}
|
||||
|
||||
public void removeElements()
|
||||
{
|
||||
for(MenuItemComponent comp : components)
|
||||
{
|
||||
super.removeChild(comp);
|
||||
}
|
||||
components.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
if(isSubMenu() && isVisible())
|
||||
{
|
||||
if(isFlagSet(FLAG_OPEN))
|
||||
{
|
||||
if(isMouseOver(mouseX, mouseY) || isOverChild(mouseX, mouseY))
|
||||
{
|
||||
timeNotHovered = -1;
|
||||
return true;
|
||||
}
|
||||
if(timeNotHovered == -1)
|
||||
{
|
||||
timeNotHovered = getGlobalClock();
|
||||
}
|
||||
if(getGlobalClock() - timeNotHovered > 10)
|
||||
{
|
||||
setOpen(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
timeNotHovered = -1;
|
||||
if(isMouseOver(mouseX, mouseY) && !ownerMenu.hasOtherMenuOpen(this))
|
||||
{
|
||||
setOpen(true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
float brigthness = isFlagSet(FLAG_OPEN) ? 0.7F : getBrightness(mouseX, mouseY);
|
||||
float minX = getBox().getMinX(0.2F);
|
||||
float minY = getBox().getMinY(0.2F);
|
||||
float maxX = Math.max(getBox().getMaxX(), minX + boxWidth);
|
||||
float maxY = getBox().getMaxY(-0.2F);
|
||||
getRenderer().setBrightness(brigthness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brigthness * 0.5F).drawFrame(minX, minY, maxX, maxY, color);
|
||||
text.setBrightness(brigthness);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
if(!isSubMenu())
|
||||
{
|
||||
setOpen(!isFlagSet(FLAG_OPEN)).notifyListeners(LISTENER_USER_ACTION);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected MenuComponent setIsSubMenu(boolean value)
|
||||
{
|
||||
if(setFlag(FLAG_SUB_MENU, value))
|
||||
{
|
||||
setFlag(FLAG_KEEP_MENU_OPEN, value);
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
MenuItemComponent comp = components.get(i);
|
||||
addConstrains(comp, createConstrains(comp));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isSubMenu()
|
||||
{
|
||||
return isFlagSet(FLAG_SUB_MENU);
|
||||
}
|
||||
|
||||
public MenuComponent setOpen(boolean open)
|
||||
{
|
||||
if(setFlag(FLAG_OPEN, open))
|
||||
{
|
||||
width = 0F;
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
GuiComponent comp = components.get(i);
|
||||
comp.setVisible(open);
|
||||
width = Math.max(width, comp.getBox().getBaseWidth());
|
||||
}
|
||||
width *= getBox().getScale();
|
||||
width += 1F;
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
components.get(i).setBoxWidth(width);
|
||||
}
|
||||
onChanged(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
protected boolean hasOtherMenuOpen(MenuComponent other)
|
||||
{
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
MenuItemComponent comp = components.get(i);
|
||||
if(comp != other && comp instanceof MenuComponent && comp.isFlagSet(FLAG_OPEN))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState()
|
||||
{
|
||||
if(isFlagSet(FLAG_OPEN) != isVisible())
|
||||
{
|
||||
boolean isOpen = isFlagSet(FLAG_OPEN);
|
||||
for(int i = 0,m=components.size();i<m;i++)
|
||||
{
|
||||
components.get(i).setVisible(isOpen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusLost()
|
||||
{
|
||||
if(!isChildFocused())
|
||||
{
|
||||
setOpen(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent t)
|
||||
{
|
||||
if(t.cast(MenuItemComponent.class).isNotClosingMenu())
|
||||
{
|
||||
return;
|
||||
}
|
||||
setOpen(false);
|
||||
if(ownerMenu != null)
|
||||
{
|
||||
ownerMenu.accept(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Menu: "+getText().getText();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,118 +1,118 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.misc;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.collections.objects.lists.ObjectList;
|
||||
import speiger.src.collections.objects.utils.ObjectLists;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
|
||||
public class CheckBoxGroup<T extends GuiComponent & ICheckBox<T>> implements Consumer<GuiComponent>
|
||||
{
|
||||
ObjectList<T> checkboxes = new ObjectArrayList<T>();
|
||||
int selectedIndex = -1;
|
||||
Runnable listener;
|
||||
|
||||
public CheckBoxGroup<T> setListener(Runnable listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public T add(T box)
|
||||
{
|
||||
checkboxes.add(box);
|
||||
if(box.isChecked())
|
||||
{
|
||||
if(selectedIndex == -1)
|
||||
{
|
||||
selectedIndex = checkboxes.indexOf(box);
|
||||
}
|
||||
else
|
||||
{
|
||||
box.setChecked(false);
|
||||
}
|
||||
}
|
||||
box.addUserActionListener(this);
|
||||
return box;
|
||||
}
|
||||
|
||||
public boolean remove(T box)
|
||||
{
|
||||
boolean result = checkboxes.remove(box);
|
||||
if(result)
|
||||
{
|
||||
if(box.isChecked())
|
||||
{
|
||||
selectedIndex = -1;
|
||||
}
|
||||
box.removeChangeListener(this);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public T getSelected()
|
||||
{
|
||||
return selectedIndex == -1 ? null : checkboxes.get(selectedIndex);
|
||||
}
|
||||
|
||||
public boolean hasSelected()
|
||||
{
|
||||
return selectedIndex != -1;
|
||||
}
|
||||
|
||||
public int getSelectedIndex()
|
||||
{
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
public List<T> getCheckBoxes()
|
||||
{
|
||||
return ObjectLists.unmodifiable(checkboxes);
|
||||
}
|
||||
|
||||
public void setChecked(int selected)
|
||||
{
|
||||
if(selectedIndex != -1)
|
||||
{
|
||||
checkboxes.get(selectedIndex).setChecked(false);
|
||||
}
|
||||
selectedIndex = selected;
|
||||
if(selectedIndex != -1)
|
||||
{
|
||||
checkboxes.get(selectedIndex).setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent t)
|
||||
{
|
||||
ICheckBox<T> box = t.tryCast(ICheckBox.class);
|
||||
if(box == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int index = checkboxes.indexOf(t);
|
||||
if(index == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(box.isChecked())
|
||||
{
|
||||
if(selectedIndex != -1)
|
||||
{
|
||||
checkboxes.get(selectedIndex).setChecked(false);
|
||||
}
|
||||
selectedIndex = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedIndex = -1;
|
||||
}
|
||||
if(listener != null)
|
||||
{
|
||||
listener.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.misc;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.collections.objects.lists.ObjectList;
|
||||
import speiger.src.collections.objects.utils.ObjectLists;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
|
||||
public class CheckBoxGroup<T extends GuiComponent & ICheckBox<T>> implements Consumer<GuiComponent>
|
||||
{
|
||||
ObjectList<T> checkboxes = new ObjectArrayList<T>();
|
||||
int selectedIndex = -1;
|
||||
Runnable listener;
|
||||
|
||||
public CheckBoxGroup<T> setListener(Runnable listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public T add(T box)
|
||||
{
|
||||
checkboxes.add(box);
|
||||
if(box.isChecked())
|
||||
{
|
||||
if(selectedIndex == -1)
|
||||
{
|
||||
selectedIndex = checkboxes.indexOf(box);
|
||||
}
|
||||
else
|
||||
{
|
||||
box.setChecked(false);
|
||||
}
|
||||
}
|
||||
box.onAction(this);
|
||||
return box;
|
||||
}
|
||||
|
||||
public boolean remove(T box)
|
||||
{
|
||||
boolean result = checkboxes.remove(box);
|
||||
if(result)
|
||||
{
|
||||
if(box.isChecked())
|
||||
{
|
||||
selectedIndex = -1;
|
||||
}
|
||||
box.removeChangeListener(this);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public T getSelected()
|
||||
{
|
||||
return selectedIndex == -1 ? null : checkboxes.get(selectedIndex);
|
||||
}
|
||||
|
||||
public boolean hasSelected()
|
||||
{
|
||||
return selectedIndex != -1;
|
||||
}
|
||||
|
||||
public int getSelectedIndex()
|
||||
{
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
public List<T> getCheckBoxes()
|
||||
{
|
||||
return ObjectLists.unmodifiable(checkboxes);
|
||||
}
|
||||
|
||||
public void setChecked(int selected)
|
||||
{
|
||||
if(selectedIndex != -1)
|
||||
{
|
||||
checkboxes.get(selectedIndex).setChecked(false);
|
||||
}
|
||||
selectedIndex = selected;
|
||||
if(selectedIndex != -1)
|
||||
{
|
||||
checkboxes.get(selectedIndex).setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent t)
|
||||
{
|
||||
ICheckBox<T> box = t.tryCast(ICheckBox.class);
|
||||
if(box == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int index = checkboxes.indexOf(t);
|
||||
if(index == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(box.isChecked())
|
||||
{
|
||||
if(selectedIndex != -1)
|
||||
{
|
||||
checkboxes.get(selectedIndex).setChecked(false);
|
||||
}
|
||||
selectedIndex = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedIndex = -1;
|
||||
}
|
||||
if(listener != null)
|
||||
{
|
||||
listener.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.misc;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
|
||||
public interface ICheckBox<T extends GuiComponent>
|
||||
{
|
||||
public boolean isChecked();
|
||||
|
||||
public T setChecked(boolean value);
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.misc;
|
||||
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
|
||||
public interface ICheckBox<T extends GuiComponent>
|
||||
{
|
||||
public boolean isChecked();
|
||||
|
||||
public T setChecked(boolean value);
|
||||
}
|
||||
|
|
|
@ -1,223 +1,223 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.special;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IKeyComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.ListComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.ScrollBarComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.list.TextListEntry;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.IFontRenderer;
|
||||
|
||||
public class ConsoleComponent extends GuiComponent implements IKeyComponent
|
||||
{
|
||||
TextFieldComponent chat = new TextFieldComponent(ColorUtils.DARK_GRAY).setCanLoseFocus(false).setInfiniteText(true).setMaxTextLength(Integer.MAX_VALUE).setFocused(true);
|
||||
ListComponent<MessageEntry> list = new ListComponent<>(ColorUtils.setA(ColorUtils.DARK_GRAY, 120), 8F);
|
||||
float lastWidth = 0F;
|
||||
List<ConsoleMessage> messages = new ObjectArrayList<>();
|
||||
Consumer<String> listener;
|
||||
int messageIterator = 0;
|
||||
boolean started = false;
|
||||
|
||||
public ConsoleComponent()
|
||||
{
|
||||
this(0F, 0F, 0F, 0F);
|
||||
}
|
||||
|
||||
public ConsoleComponent(float x, float y, float width, float height)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
}
|
||||
|
||||
public ConsoleComponent setListener(Consumer<String> listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
chat.getRawText().setTextScale(0.45F);
|
||||
chat.addUserActionListener(this::onEnter);
|
||||
list.setSelectionMode(ListComponent.SELECTION_MODE_DISABLE);
|
||||
list.setStartAtBottom(true);
|
||||
addChild(chat, new Constrains(new ParentConstrain(), new ParentConstrain(12F).invert(), new ParentConstrain(), new PixelConstrain(12F)));
|
||||
addChild(list, new Constrains(new ParentConstrain(), new ParentConstrain(100).invert(), new RelativeConstrain(0.8F), new PixelConstrain(88)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState()
|
||||
{
|
||||
float width = list.getBox().getWidth();
|
||||
if(lastWidth != width)
|
||||
{
|
||||
lastWidth = width;
|
||||
updateMessages();
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateMessages()
|
||||
{
|
||||
list.clear();
|
||||
for(int i = 0,m=messages.size();i<m;i++)
|
||||
{
|
||||
ConsoleMessage message = messages.get(i);
|
||||
addMessage(message.getMessage(), message.getMessageId(), false);
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleVisiblity()
|
||||
{
|
||||
setVisible(!isVisible());
|
||||
chat.setFocused(isVisible());
|
||||
}
|
||||
|
||||
private void onEnter()
|
||||
{
|
||||
if(!chat.isVisible())
|
||||
{
|
||||
chat.setText("");
|
||||
return;
|
||||
}
|
||||
if(chat.getText().isEmpty()) return;
|
||||
addMessage(chat.getText(), 0);
|
||||
chat.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptingInput()
|
||||
{
|
||||
return isVisible();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockingMovement()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyPressed(int key)
|
||||
{
|
||||
if(key == GLFW.GLFW_KEY_UP)
|
||||
{
|
||||
if(messageIterator < messages.size())
|
||||
{
|
||||
chat.setText(messages.get((messages.size()-1 - messageIterator)).getMessage()).setCurserToEnd();
|
||||
messageIterator++;
|
||||
started = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if(key == GLFW.GLFW_KEY_DOWN)
|
||||
{
|
||||
if(messageIterator > 0)
|
||||
{
|
||||
messageIterator--;
|
||||
chat.setText(messages.get((messages.size()-1 - messageIterator)).getMessage()).setCurserToEnd();
|
||||
}
|
||||
else if(started)
|
||||
{
|
||||
chat.setText("").setCurserToEnd();
|
||||
started = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addMessage(String text)
|
||||
{
|
||||
addMessage(text, 0);
|
||||
}
|
||||
|
||||
public void addMessage(String text, int messageId)
|
||||
{
|
||||
addMessage(text, messageId, true);
|
||||
}
|
||||
|
||||
private void addMessage(String text, int messageId, boolean add)
|
||||
{
|
||||
if(listener != null && text.startsWith("/"))
|
||||
{
|
||||
listener.accept(text.substring(1));
|
||||
return;
|
||||
}
|
||||
ScrollBarComponent scroll = list.getVerticalBar();
|
||||
boolean atEnd = scroll.isAtEnd();
|
||||
float width = (list.getBox().getWidth() -5F) / 0.45F;
|
||||
for(String s : getGui().getFont().split(text, width, IFontRenderer.SPECIAL))
|
||||
{
|
||||
list.add(new MessageEntry(s, messageId));
|
||||
}
|
||||
if(atEnd) scroll.setScrollEnd();
|
||||
if(add)
|
||||
{
|
||||
messages.add(new ConsoleMessage(messageId, text));
|
||||
messageIterator = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void clearMessages()
|
||||
{
|
||||
messages.clear();
|
||||
list.clear();
|
||||
messageIterator = 0;
|
||||
}
|
||||
|
||||
public void removeMessage(int messageId)
|
||||
{
|
||||
messages.removeIf(T -> T.getMessageId() == messageId);
|
||||
list.removeIf(T -> T.getMessageId() == messageId);
|
||||
}
|
||||
|
||||
private static class ConsoleMessage
|
||||
{
|
||||
int messageId;
|
||||
String message;
|
||||
|
||||
public ConsoleMessage(int messageId, String message)
|
||||
{
|
||||
this.messageId = messageId;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
public int getMessageId()
|
||||
{
|
||||
return messageId;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MessageEntry extends TextListEntry
|
||||
{
|
||||
int messageId;
|
||||
|
||||
public MessageEntry(String s, int messageId)
|
||||
{
|
||||
super(s);
|
||||
this.messageId = messageId;
|
||||
setScale(0.45F);
|
||||
}
|
||||
|
||||
public int getMessageId()
|
||||
{
|
||||
return messageId;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.special;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.base.IKeyComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.ListComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.ScrollBarComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.list.TextListEntry;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.IFontRenderer;
|
||||
|
||||
public class ConsoleComponent extends GuiComponent implements IKeyComponent
|
||||
{
|
||||
TextFieldComponent chat = new TextFieldComponent(ColorUtils.DARK_GRAY).setCanLoseFocus(false).setInfiniteText(true).setMaxTextLength(Integer.MAX_VALUE).setFocused(true);
|
||||
ListComponent<MessageEntry> list = new ListComponent<>(ColorUtils.setA(ColorUtils.DARK_GRAY, 120), 8F);
|
||||
float lastWidth = 0F;
|
||||
List<ConsoleMessage> messages = new ObjectArrayList<>();
|
||||
Consumer<String> listener;
|
||||
int messageIterator = 0;
|
||||
boolean started = false;
|
||||
|
||||
public ConsoleComponent()
|
||||
{
|
||||
this(0F, 0F, 0F, 0F);
|
||||
}
|
||||
|
||||
public ConsoleComponent(float x, float y, float width, float height)
|
||||
{
|
||||
super(x, y, width, height);
|
||||
}
|
||||
|
||||
public ConsoleComponent setListener(Consumer<String> listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
chat.getRawText().setTextScale(0.45F);
|
||||
chat.onAction(this::onEnter);
|
||||
list.setSelectionMode(ListComponent.SELECTION_MODE_DISABLE);
|
||||
list.setStartAtBottom(true);
|
||||
addChild(chat, new Constrains(new ParentConstrain(), new ParentConstrain(12F).invert(), new ParentConstrain(), new PixelConstrain(12F)));
|
||||
addChild(list, new Constrains(new ParentConstrain(), new ParentConstrain(100).invert(), new RelativeConstrain(0.8F), new PixelConstrain(88)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState()
|
||||
{
|
||||
float width = list.getBox().getWidth();
|
||||
if(lastWidth != width)
|
||||
{
|
||||
lastWidth = width;
|
||||
updateMessages();
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateMessages()
|
||||
{
|
||||
list.clear();
|
||||
for(int i = 0,m=messages.size();i<m;i++)
|
||||
{
|
||||
ConsoleMessage message = messages.get(i);
|
||||
addMessage(message.getMessage(), message.getMessageId(), false);
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleVisiblity()
|
||||
{
|
||||
setVisible(!isVisible());
|
||||
chat.setFocused(isVisible());
|
||||
}
|
||||
|
||||
private void onEnter()
|
||||
{
|
||||
if(!chat.isVisible())
|
||||
{
|
||||
chat.setText("");
|
||||
return;
|
||||
}
|
||||
if(chat.getText().isEmpty()) return;
|
||||
addMessage(chat.getText(), 0);
|
||||
chat.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptingInput()
|
||||
{
|
||||
return isVisible();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockingMovement()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyPressed(int key)
|
||||
{
|
||||
if(key == GLFW.GLFW_KEY_UP)
|
||||
{
|
||||
if(messageIterator < messages.size())
|
||||
{
|
||||
chat.setText(messages.get((messages.size()-1 - messageIterator)).getMessage()).setCurserToEnd();
|
||||
messageIterator++;
|
||||
started = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if(key == GLFW.GLFW_KEY_DOWN)
|
||||
{
|
||||
if(messageIterator > 0)
|
||||
{
|
||||
messageIterator--;
|
||||
chat.setText(messages.get((messages.size()-1 - messageIterator)).getMessage()).setCurserToEnd();
|
||||
}
|
||||
else if(started)
|
||||
{
|
||||
chat.setText("").setCurserToEnd();
|
||||
started = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addMessage(String text)
|
||||
{
|
||||
addMessage(text, 0);
|
||||
}
|
||||
|
||||
public void addMessage(String text, int messageId)
|
||||
{
|
||||
addMessage(text, messageId, true);
|
||||
}
|
||||
|
||||
private void addMessage(String text, int messageId, boolean add)
|
||||
{
|
||||
if(listener != null && text.startsWith("/"))
|
||||
{
|
||||
listener.accept(text.substring(1));
|
||||
return;
|
||||
}
|
||||
ScrollBarComponent scroll = list.getVerticalBar();
|
||||
boolean atEnd = scroll.isAtEnd();
|
||||
float width = (list.getBox().getWidth() -5F) / 0.45F;
|
||||
for(String s : getGui().getFont().split(text, width, IFontRenderer.SPECIAL))
|
||||
{
|
||||
list.add(new MessageEntry(s, messageId));
|
||||
}
|
||||
if(atEnd) scroll.setScrollEnd();
|
||||
if(add)
|
||||
{
|
||||
messages.add(new ConsoleMessage(messageId, text));
|
||||
messageIterator = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void clearMessages()
|
||||
{
|
||||
messages.clear();
|
||||
list.clear();
|
||||
messageIterator = 0;
|
||||
}
|
||||
|
||||
public void removeMessage(int messageId)
|
||||
{
|
||||
messages.removeIf(T -> T.getMessageId() == messageId);
|
||||
list.removeIf(T -> T.getMessageId() == messageId);
|
||||
}
|
||||
|
||||
private static class ConsoleMessage
|
||||
{
|
||||
int messageId;
|
||||
String message;
|
||||
|
||||
public ConsoleMessage(int messageId, String message)
|
||||
{
|
||||
this.messageId = messageId;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
public int getMessageId()
|
||||
{
|
||||
return messageId;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MessageEntry extends TextListEntry
|
||||
{
|
||||
int messageId;
|
||||
|
||||
public MessageEntry(String s, int messageId)
|
||||
{
|
||||
super(s);
|
||||
this.messageId = messageId;
|
||||
setScale(0.45F);
|
||||
}
|
||||
|
||||
public int getMessageId()
|
||||
{
|
||||
return messageId;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,129 +1,129 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.tree;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiBase;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.window.debug.PieProfilerWindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.Align;
|
||||
import speiger.src.coreengine.rendering.input.Keyboard;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
|
||||
|
||||
public class ProfilerTreeEntry extends BaseTreeEntry
|
||||
{
|
||||
TextComponent text = new TextComponent().limit(false).align(Align.LEFT_TOP, Align.LEFT_TOP).special(true).setTextScale(0.4F).set(0F, 1F).cast();
|
||||
IProfilerEntry entry;
|
||||
|
||||
public ProfilerTreeEntry(IProfilerEntry entry)
|
||||
{
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getWidth()
|
||||
{
|
||||
return text.getMetadata().getMaxWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(GuiComponent comp, GuiBase owner)
|
||||
{
|
||||
super.init(comp, owner);
|
||||
text.setOwner(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(GuiComponent comp, float scale)
|
||||
{
|
||||
text.setScale(scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosed()
|
||||
{
|
||||
text.onClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFixedUpdate()
|
||||
{
|
||||
if(text.length() > 0 && (Keyboard.isAltDown() || text.getGui().getGlobalClock() % 2 != 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(entry.getName()).append(": ");
|
||||
builder.append(getColor(entry.getMinTime())).append(getTime(entry.getMinTime())).append("§<reset>").append(" / ");
|
||||
builder.append(getColor(entry.getNanoTime())).append(getTime(entry.getNanoTime())).append("§<reset>").append(" / ");
|
||||
builder.append(getColor(entry.getMaxTime())).append(getTime(entry.getMaxTime())).append("§<reset>");
|
||||
text.setText(builder.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRender(GuiComponent comp, boolean enabled, int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
text.setEnabled(enabled).render(mouseX, mouseY, particalTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectTooltips(GuiComponent comp, int mouseX, int mouseY, float particalTicks, Map<UUID, GuiComponent> collector)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return entry.getPathName().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(obj instanceof ProfilerTreeEntry)
|
||||
{
|
||||
return ((ProfilerTreeEntry)obj).entry == entry;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getTime(long time)
|
||||
{
|
||||
if(time >= 2000000L)
|
||||
{
|
||||
return PieProfilerWindowComponent.PERCENT_FORMAT.format(time / 1000000.0D) + "ms";
|
||||
}
|
||||
if(time >= 2000L)
|
||||
{
|
||||
return PieProfilerWindowComponent.PERCENT_FORMAT.format(time / 1000.0D) + "µs";
|
||||
}
|
||||
return PieProfilerWindowComponent.PERCENT_FORMAT.format(time) + "ns";
|
||||
}
|
||||
|
||||
public String getColor(long time)
|
||||
{
|
||||
time /= 1000000L;
|
||||
if(time < 1)
|
||||
{
|
||||
return "§<color="+ColorUtils.LIGHT_BLUE+">";
|
||||
}
|
||||
if(time >= 12)
|
||||
{
|
||||
return "§<color="+ColorUtils.RED+">";
|
||||
}
|
||||
if(time >= 5)
|
||||
{
|
||||
return "§<color="+ColorUtils.YELLOW+">";
|
||||
}
|
||||
return "§<color="+ColorUtils.GREEN+">";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return entry.getPathName();
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.tree;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.GuiBase;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.window.debug.PieProfilerWindow;
|
||||
import speiger.src.coreengine.rendering.gui.helper.Align;
|
||||
import speiger.src.coreengine.rendering.input.Keyboard;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
|
||||
|
||||
public class ProfilerTreeEntry extends BaseTreeEntry
|
||||
{
|
||||
TextComponent text = new TextComponent().limit(false).align(Align.LEFT_TOP, Align.LEFT_TOP).special(true).setTextScale(0.4F).set(0F, 1F).cast();
|
||||
IProfilerEntry entry;
|
||||
|
||||
public ProfilerTreeEntry(IProfilerEntry entry)
|
||||
{
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getWidth()
|
||||
{
|
||||
return text.getMetadata().getMaxWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(GuiComponent comp, GuiBase owner)
|
||||
{
|
||||
super.init(comp, owner);
|
||||
text.setOwner(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(GuiComponent comp, float scale)
|
||||
{
|
||||
text.setScale(scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosed()
|
||||
{
|
||||
text.onClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFixedUpdate()
|
||||
{
|
||||
if(text.length() > 0 && (Keyboard.isAltDown() || text.getGui().getGlobalClock() % 2 != 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(entry.getName()).append(": ");
|
||||
builder.append(getColor(entry.getMinTime())).append(getTime(entry.getMinTime())).append("§<reset>").append(" / ");
|
||||
builder.append(getColor(entry.getNanoTime())).append(getTime(entry.getNanoTime())).append("§<reset>").append(" / ");
|
||||
builder.append(getColor(entry.getMaxTime())).append(getTime(entry.getMaxTime())).append("§<reset>");
|
||||
text.setText(builder.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRender(GuiComponent comp, boolean enabled, int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
text.setEnabled(enabled).render(mouseX, mouseY, particalTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectTooltips(GuiComponent comp, int mouseX, int mouseY, float particalTicks, Map<UUID, GuiComponent> collector)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return entry.getPathName().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(obj instanceof ProfilerTreeEntry)
|
||||
{
|
||||
return ((ProfilerTreeEntry)obj).entry == entry;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getTime(long time)
|
||||
{
|
||||
if(time >= 2000000L)
|
||||
{
|
||||
return PieProfilerWindow.PERCENT_FORMAT.format(time / 1000000.0D) + "ms";
|
||||
}
|
||||
if(time >= 2000L)
|
||||
{
|
||||
return PieProfilerWindow.PERCENT_FORMAT.format(time / 1000.0D) + "µs";
|
||||
}
|
||||
return PieProfilerWindow.PERCENT_FORMAT.format(time) + "ns";
|
||||
}
|
||||
|
||||
public String getColor(long time)
|
||||
{
|
||||
time /= 1000000L;
|
||||
if(time < 1)
|
||||
{
|
||||
return "§<color="+ColorUtils.LIGHT_BLUE+">";
|
||||
}
|
||||
if(time >= 12)
|
||||
{
|
||||
return "§<color="+ColorUtils.RED+">";
|
||||
}
|
||||
if(time >= 5)
|
||||
{
|
||||
return "§<color="+ColorUtils.YELLOW+">";
|
||||
}
|
||||
return "§<color="+ColorUtils.GREEN+">";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return entry.getPathName();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,153 +1,153 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.window.color;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.math.misc.Facing;
|
||||
import speiger.src.coreengine.math.vector.floats.Vec2f;
|
||||
import speiger.src.coreengine.rendering.gui.UITextures;
|
||||
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.GradientSliderComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.SliderComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.icon.IIcon;
|
||||
import speiger.src.coreengine.rendering.gui.components.icon.TexturedIcon;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.GuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
|
||||
import speiger.src.coreengine.utils.functions.Functions;
|
||||
import speiger.src.coreengine.utils.helpers.InternalThreadPools;
|
||||
|
||||
public class ColorPickerWindowComponent extends WindowComponent
|
||||
{
|
||||
IntConsumer listener;
|
||||
IIcon wheelIcon = new TexturedIcon(UITextures.COLOR_WHEEL);
|
||||
IGuiBox wheelBox = new GuiBox(15, 10, 70, 70);
|
||||
IGuiBox selectedBox = new GuiBox(5F, 94F, 50F, 10F);
|
||||
int[] colors = new int[]{ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0)};
|
||||
SliderComponent brightness = new GradientSliderComponent(95, 13, 17, 76, 0, 100, 0, ColorUtils.GRAY, colors[2], colors[3], Facing.NORTH, null).setScrollEffect(-1).setVertical(true);
|
||||
SliderComponent saturation = new GradientSliderComponent(110, 13, 17, 76, 0, 100, 0, ColorUtils.GRAY, colors[0], colors[1], Facing.NORTH, null).setScrollEffect(-1).setVertical(true);
|
||||
TextFieldComponent code = new TextFieldComponent(60, 94, 104, 20, ColorUtils.DARK_GRAY).setValidator(Functions.NUMBERS_ONLY).setMaxTextLength(8);
|
||||
float[] hsv = new float[3];
|
||||
IGuiBox[] colorBoxes;
|
||||
ColorPool pool;
|
||||
|
||||
public ColorPickerWindowComponent(float x, float y, ColorPool pool, int defaultColor, IntConsumer listener, String name)
|
||||
{
|
||||
super(x, y, 125, 140, FIXED_SIZE_POPUP, name);
|
||||
this.pool = pool;
|
||||
this.listener = listener;
|
||||
hsv = ColorUtils.toHue(defaultColor);
|
||||
colorBoxes = new IGuiBox[Math.min(18, pool.size())];
|
||||
for(int i = 0,m=colorBoxes.length;i<m;i++)
|
||||
{
|
||||
addBox(colorBoxes[i] = new GuiBox(5 + ((i % 9) * 12), 108 + (i >= 9 ? 12 : 0), 10, 10));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
addBox(wheelBox);
|
||||
addBox(selectedBox);
|
||||
addChild(brightness.addChangeListener(minimizedListener).addUserActionListener(T -> setColor(hsv[0], hsv[1], T.cast(SliderComponent.class).getValue() * 0.01F)));
|
||||
addChild(saturation.addChangeListener(minimizedListener).addUserActionListener(T -> setColor(hsv[0], T.cast(SliderComponent.class).getValue() * 0.01F, hsv[2])));
|
||||
addChild(code.setScale(0.5F).addChangeListener(minimizedListener).addUserActionListener(T -> onTyped()));
|
||||
addChild(new ButtonComponent(0F, 0F, 0F, 20F, "Select", ColorUtils.GREEN).setScale(0.4F).addUserActionListener(T -> apply()), new Constrains(null, new ParentConstrain(8F).invert(), new RelativeConstrain(0.5F / 0.4F), null));
|
||||
addChild(new ButtonComponent(0F, 0F, 0F, 20F, "Cancel", ColorUtils.RED).setScale(0.4F).addUserActionListener(T -> T.getGui().removeComponent(this)), new Constrains(new RelativeConstrain(0.5F), new ParentConstrain(8F).invert(), new RelativeConstrain(0.5F / 0.4F), null));
|
||||
setColor(hsv[0], hsv[1], hsv[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPopup()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
super.renderSelf(mouseX, mouseY, particalTicks);
|
||||
wheelIcon.render(getRenderer().translate(0F, 0F, 0.01F).setBrightness(hsv[1]), wheelBox);
|
||||
getRenderer().setBrightness(1F);
|
||||
for(int i = 0,m=colorBoxes.length;i<m;i++)
|
||||
{
|
||||
IGuiBox box = colorBoxes[i];
|
||||
getRenderer().drawQuad(box, pool.getColor(i)).drawFrame(box, ColorUtils.DARK_GRAY);
|
||||
}
|
||||
getRenderer().drawQuad(selectedBox, colors[4]).drawFrame(selectedBox, ColorUtils.DARK_GRAY);
|
||||
float centerX = wheelBox.getCenterX();
|
||||
float centerY = wheelBox.getCenterY();
|
||||
Vec2f pos = InternalThreadPools.VEC2F.get().set(centerX, centerY).add(0F, -(hsv[2] * 33F)).rotate((float)Math.toRadians(-hsv[0] * 360F), centerX, centerY);
|
||||
getRenderer().drawQuad(pos.getX() - 1F, pos.getY() - 1F, pos.getX() + 1F, pos.getY() + 1, 0.1F, ColorUtils.BLACK);
|
||||
InternalThreadPools.VEC2F.accept(pos);
|
||||
getRenderer().translate(0F, 0F, -0.01F);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void onTyped()
|
||||
{
|
||||
try
|
||||
{
|
||||
int color = Integer.decode(code.getText());
|
||||
float[] hsv = Color.RGBtoHSB((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF, new float[3]);
|
||||
setColor(hsv[0], hsv[1], hsv[2]);
|
||||
}
|
||||
catch(Exception e){}
|
||||
}
|
||||
|
||||
public void apply()
|
||||
{
|
||||
pool.addColor(colors[4]);
|
||||
listener.accept(colors[4]);
|
||||
getGui().removeComponent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
return wheelBox.isColiding(mouseX, mouseY) ? onChanged(mouseX, mouseY) : super.onClick(button, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(int mouseX, int mouseY)
|
||||
{
|
||||
return super.onDrag(mouseX, mouseY) || (wheelBox.isColiding(mouseX, mouseY) ? onChanged(mouseX, mouseY) : false);
|
||||
}
|
||||
|
||||
private boolean onChanged(int mouseX, int mouseY)
|
||||
{
|
||||
Vec2f pos = InternalThreadPools.VEC2F.get().set(mouseX, mouseY);
|
||||
float radius = (float)pos.distanceTo(wheelBox.getCenterX(), wheelBox.getCenterY());
|
||||
if(radius > 38)
|
||||
{
|
||||
InternalThreadPools.VEC2F.accept(pos);
|
||||
return false;
|
||||
}
|
||||
float hue = (pos.directionAngle(wheelBox.getCenterX(), wheelBox.getCenterY()) + 180F) % 360F;
|
||||
setColor(hue / 360F, hsv[1], radius / 33F);
|
||||
InternalThreadPools.VEC2F.accept(pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void setColor(float hue, float saturation, float brightness)
|
||||
{
|
||||
hsv[0] = MathUtils.clamp(0F, 1F, hue);
|
||||
hsv[1] = MathUtils.clamp(0F, 1F, saturation);
|
||||
hsv[2] = MathUtils.clamp(0F, 1F, brightness);
|
||||
colors[0] = ColorUtils.toRGB(hsv[0], 0F, 1F);
|
||||
colors[1] = ColorUtils.toRGB(hsv[0], 1F, 1F);
|
||||
colors[2] = ColorUtils.toRGB(hsv[0], 1F, 0F);
|
||||
colors[3] = ColorUtils.toRGB(hsv[0], 1F, 1F);
|
||||
colors[4] = ColorUtils.toRGB(hsv[0], hsv[1], hsv[2]);
|
||||
code.setText(ColorUtils.getHTMLCode(colors[4], false));
|
||||
this.brightness.setValue((int)(hsv[2] * 100F));
|
||||
this.saturation.setValue((int)(hsv[1] * 100F));
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.window.color;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.math.misc.Facing;
|
||||
import speiger.src.coreengine.math.vector.floats.Vec2f;
|
||||
import speiger.src.coreengine.rendering.gui.UITextures;
|
||||
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.GradientSliderComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.SliderComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.icon.IIcon;
|
||||
import speiger.src.coreengine.rendering.gui.components.icon.TexturedIcon;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.GuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
|
||||
import speiger.src.coreengine.utils.functions.Functions;
|
||||
import speiger.src.coreengine.utils.helpers.InternalThreadPools;
|
||||
|
||||
public class ColorPickerWindowComponent extends WindowComponent
|
||||
{
|
||||
IntConsumer listener;
|
||||
IIcon wheelIcon = new TexturedIcon(UITextures.COLOR_WHEEL);
|
||||
IGuiBox wheelBox = new GuiBox(15, 10, 70, 70);
|
||||
IGuiBox selectedBox = new GuiBox(5F, 94F, 50F, 10F);
|
||||
int[] colors = new int[]{ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0), ColorUtils.rgb(0)};
|
||||
SliderComponent brightness = new GradientSliderComponent(95, 13, 17, 76, 0, 100, 0, ColorUtils.GRAY, colors[2], colors[3], Facing.NORTH, null).setScrollEffect(-1).setVertical(true);
|
||||
SliderComponent saturation = new GradientSliderComponent(110, 13, 17, 76, 0, 100, 0, ColorUtils.GRAY, colors[0], colors[1], Facing.NORTH, null).setScrollEffect(-1).setVertical(true);
|
||||
TextFieldComponent code = new TextFieldComponent(60, 94, 104, 20, ColorUtils.DARK_GRAY).setValidator(Functions.NUMBERS_ONLY).setMaxTextLength(8);
|
||||
float[] hsv = new float[3];
|
||||
IGuiBox[] colorBoxes;
|
||||
ColorPool pool;
|
||||
|
||||
public ColorPickerWindowComponent(float x, float y, ColorPool pool, int defaultColor, IntConsumer listener, String name)
|
||||
{
|
||||
super(x, y, 125, 140, FIXED_SIZE_POPUP, name);
|
||||
this.pool = pool;
|
||||
this.listener = listener;
|
||||
hsv = ColorUtils.toHue(defaultColor);
|
||||
colorBoxes = new IGuiBox[Math.min(18, pool.size())];
|
||||
for(int i = 0,m=colorBoxes.length;i<m;i++)
|
||||
{
|
||||
addBox(colorBoxes[i] = new GuiBox(5 + ((i % 9) * 12), 108 + (i >= 9 ? 12 : 0), 10, 10));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
addBox(wheelBox);
|
||||
addBox(selectedBox);
|
||||
addChild(brightness.onChange(minimizedListener).onAction(T -> setColor(hsv[0], hsv[1], T.cast(SliderComponent.class).getValue() * 0.01F)));
|
||||
addChild(saturation.onChange(minimizedListener).onAction(T -> setColor(hsv[0], T.cast(SliderComponent.class).getValue() * 0.01F, hsv[2])));
|
||||
addChild(code.setScale(0.5F).onChange(minimizedListener).onAction(T -> onTyped()));
|
||||
addChild(new ButtonComponent(0F, 0F, 0F, 20F, "Select", ColorUtils.GREEN).setScale(0.4F).onAction(T -> apply()), new Constrains(null, new ParentConstrain(8F).invert(), new RelativeConstrain(0.5F / 0.4F), null));
|
||||
addChild(new ButtonComponent(0F, 0F, 0F, 20F, "Cancel", ColorUtils.RED).setScale(0.4F).onAction(T -> T.getGui().removeComponent(this)), new Constrains(new RelativeConstrain(0.5F), new ParentConstrain(8F).invert(), new RelativeConstrain(0.5F / 0.4F), null));
|
||||
setColor(hsv[0], hsv[1], hsv[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPopup()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
super.renderSelf(mouseX, mouseY, particalTicks);
|
||||
wheelIcon.render(getRenderer().translate(0F, 0F, 0.01F).setBrightness(hsv[1]), wheelBox);
|
||||
getRenderer().setBrightness(1F);
|
||||
for(int i = 0,m=colorBoxes.length;i<m;i++)
|
||||
{
|
||||
IGuiBox box = colorBoxes[i];
|
||||
getRenderer().drawQuad(box, pool.getColor(i)).drawFrame(box, ColorUtils.DARK_GRAY);
|
||||
}
|
||||
getRenderer().drawQuad(selectedBox, colors[4]).drawFrame(selectedBox, ColorUtils.DARK_GRAY);
|
||||
float centerX = wheelBox.getCenterX();
|
||||
float centerY = wheelBox.getCenterY();
|
||||
Vec2f pos = InternalThreadPools.VEC2F.get().set(centerX, centerY).add(0F, -(hsv[2] * 33F)).rotate((float)Math.toRadians(-hsv[0] * 360F), centerX, centerY);
|
||||
getRenderer().drawQuad(pos.getX() - 1F, pos.getY() - 1F, pos.getX() + 1F, pos.getY() + 1, 0.1F, ColorUtils.BLACK);
|
||||
InternalThreadPools.VEC2F.accept(pos);
|
||||
getRenderer().translate(0F, 0F, -0.01F);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void onTyped()
|
||||
{
|
||||
try
|
||||
{
|
||||
int color = Integer.decode(code.getText());
|
||||
float[] hsv = Color.RGBtoHSB((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF, new float[3]);
|
||||
setColor(hsv[0], hsv[1], hsv[2]);
|
||||
}
|
||||
catch(Exception e){}
|
||||
}
|
||||
|
||||
public void apply()
|
||||
{
|
||||
pool.addColor(colors[4]);
|
||||
listener.accept(colors[4]);
|
||||
getGui().removeComponent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
return wheelBox.isColiding(mouseX, mouseY) ? onChanged(mouseX, mouseY) : super.onClick(button, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(int mouseX, int mouseY)
|
||||
{
|
||||
return super.onDrag(mouseX, mouseY) || (wheelBox.isColiding(mouseX, mouseY) ? onChanged(mouseX, mouseY) : false);
|
||||
}
|
||||
|
||||
private boolean onChanged(int mouseX, int mouseY)
|
||||
{
|
||||
Vec2f pos = InternalThreadPools.VEC2F.get().set(mouseX, mouseY);
|
||||
float radius = (float)pos.distanceTo(wheelBox.getCenterX(), wheelBox.getCenterY());
|
||||
if(radius > 38)
|
||||
{
|
||||
InternalThreadPools.VEC2F.accept(pos);
|
||||
return false;
|
||||
}
|
||||
float hue = (pos.directionAngle(wheelBox.getCenterX(), wheelBox.getCenterY()) + 180F) % 360F;
|
||||
setColor(hue / 360F, hsv[1], radius / 33F);
|
||||
InternalThreadPools.VEC2F.accept(pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void setColor(float hue, float saturation, float brightness)
|
||||
{
|
||||
hsv[0] = MathUtils.clamp(0F, 1F, hue);
|
||||
hsv[1] = MathUtils.clamp(0F, 1F, saturation);
|
||||
hsv[2] = MathUtils.clamp(0F, 1F, brightness);
|
||||
colors[0] = ColorUtils.toRGB(hsv[0], 0F, 1F);
|
||||
colors[1] = ColorUtils.toRGB(hsv[0], 1F, 1F);
|
||||
colors[2] = ColorUtils.toRGB(hsv[0], 1F, 0F);
|
||||
colors[3] = ColorUtils.toRGB(hsv[0], 1F, 1F);
|
||||
colors[4] = ColorUtils.toRGB(hsv[0], hsv[1], hsv[2]);
|
||||
code.setText(ColorUtils.getHTMLCode(colors[4], false));
|
||||
this.brightness.setValue((int)(hsv[2] * 100F));
|
||||
this.saturation.setValue((int)(hsv[1] * 100F));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,306 +1,324 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.window.debug;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.collections.objects.utils.ObjectLists;
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.math.vector.floats.Vec2f;
|
||||
import speiger.src.coreengine.rendering.gui.GuiManager;
|
||||
import speiger.src.coreengine.rendering.gui.base.IKeyComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.PieComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.PieComponent.IPieIndex;
|
||||
import speiger.src.coreengine.rendering.gui.components.PieComponent.PieIndex;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.Align;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
|
||||
import speiger.src.coreengine.rendering.input.Keyboard;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.ProfilerData;
|
||||
|
||||
public class PieProfilerWindowComponent extends WindowComponent
|
||||
implements Supplier<List<IPieIndex>>, IKeyComponent
|
||||
{
|
||||
public static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("##0.00");
|
||||
|
||||
PieComponent pie = new PieComponent(127, this);
|
||||
ButtonComponent[] buttons = new ButtonComponent[3];
|
||||
TextComponent[] extraFeatures = new TextComponent[3];
|
||||
List<TextComponent[]> entries = new ObjectArrayList<TextComponent[]>();
|
||||
int textInUse = 0;
|
||||
IProfiler profiler;
|
||||
IProfilerEntry currentEntry;
|
||||
String entryName;
|
||||
List<ProfilerData> lastValues = null;
|
||||
|
||||
public PieProfilerWindowComponent(float x, float y, float width, float height, String name)
|
||||
{
|
||||
super(x, y, width, height, DEFAULT_FLAGS, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMoveIntoForground()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
addChild(pie.setAutoUpdate(true).set(0F, 5F).addChangeListener(minimizedListener), new Constrains(null, null, new ParentConstrain(), new DynamicConstrain(this::calculatePieHeight)));
|
||||
buttons[0] = createButton(0, "Client");
|
||||
buttons[1] = createButton(1, "GPU");
|
||||
buttons[2] = createButton(2, "Server");
|
||||
extraFeatures[0] = new TextComponent(0F, 0F, 18F, 5.5F).setTextScale(0.3F).setText("[0] Back").align(Align.LEFT_TOP, Align.CENTER);
|
||||
extraFeatures[0].addChangeListener(T -> T.setVisible(!isMinimized() && currentEntry != null && currentEntry.getParent() != null));
|
||||
addChild(extraFeatures[0], new Constrains(null, new DynamicConstrain(() -> pie.getBox().getBaseHeight() + (-5.5F)), new PixelConstrain(38).setInverted(), null));
|
||||
|
||||
extraFeatures[1] = new TextComponent(0F, 0F, 0F, 7F).setTextScale(0.4F).setText("Client Thread");
|
||||
addChild(extraFeatures[1].addChangeListener(minimizedListener), new Constrains(null, new PixelConstrain(8F), new ParentConstrain(), null));
|
||||
extraFeatures[2] = new TextComponent(0F, 0F, 0F, 6F).setTextScale(0.33F).setText("Client");
|
||||
addChild(extraFeatures[2].addChangeListener(minimizedListener), new Constrains(null, new PixelConstrain(15F), new ParentConstrain(), null));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosed()
|
||||
{
|
||||
super.onClosed();
|
||||
if(profiler != null)
|
||||
{
|
||||
profiler.disable();
|
||||
profiler = null;
|
||||
}
|
||||
}
|
||||
|
||||
public PieProfilerWindowComponent setProfiler(IProfiler profiler, String root)
|
||||
{
|
||||
if(this.profiler != null)
|
||||
{
|
||||
buttons[getProfilerIndex(this.profiler)].setEnabled(true);
|
||||
this.profiler.disable();
|
||||
}
|
||||
this.profiler = profiler;
|
||||
if(profiler != null)
|
||||
{
|
||||
profiler.enable();
|
||||
setCurrentEntry(root);
|
||||
buttons[getProfilerIndex(this.profiler)].setEnabled(false);
|
||||
extraFeatures[1].setText(profiler.getName());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public PieProfilerWindowComponent setCurrentEntry(String name)
|
||||
{
|
||||
entryName = name;
|
||||
currentEntry = profiler.getEntry(name);
|
||||
lastValues = null;
|
||||
extraFeatures[2].setText(currentEntry == null ? "Unknown" : currentEntry.getName());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
for(int i = 0,m=entries.size();i<m;i++)
|
||||
{
|
||||
TextComponent[] comp = entries.get(i);
|
||||
float brightness = comp[0].isTopHovered(mouseX, mouseY) || comp[1].isTopHovered(mouseX, mouseY) || comp[2].isTopHovered(mouseX, mouseY) ? 0.7F : 1F;
|
||||
comp[0].setBrightness(brightness);
|
||||
comp[1].setBrightness(brightness);
|
||||
comp[2].setBrightness(brightness);
|
||||
}
|
||||
extraFeatures[0].setBrightness(extraFeatures[0].isHovered(mouseX, mouseY) ? 0.7F : 1F);
|
||||
return super.updateSelf(mouseX, mouseY, particalTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fixedUpdateSelf()
|
||||
{
|
||||
if(profiler == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(currentEntry == null)
|
||||
{
|
||||
setCurrentEntry(entryName);
|
||||
return true;
|
||||
}
|
||||
if(currentEntry.getNanoTime() == 0L || (Keyboard.isAltDown() && lastValues != null) || (lastValues != null && getGlobalClock() % 2 != 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
while(entries.size() < currentEntry.getChildCount() + 1)
|
||||
{
|
||||
entries.add(new TextComponent[] {createComponent(0), createComponent(1), createComponent(2) });
|
||||
}
|
||||
boolean lastEmpty = lastValues == null;
|
||||
lastValues = currentEntry.getData();
|
||||
int last = textInUse;
|
||||
textInUse = lastValues.size();
|
||||
for(int i = 0;i < textInUse;i++)
|
||||
{
|
||||
ProfilerData data = lastValues.get(i);
|
||||
TextComponent[] info = entries.get(i);
|
||||
int color = data.getColor();
|
||||
info[0].setMassChanging(TextComponent.class).textColor(color).setText("[" + (i + 1) + "] " + data.getName()).finishMassChanging();
|
||||
info[1].setMassChanging(TextComponent.class).textColor(color).setText(PERCENT_FORMAT.format(data.getEffect()) + "%").finishMassChanging();
|
||||
info[2].setMassChanging(TextComponent.class).textColor(color).setText(PERCENT_FORMAT.format(data.getTotalEffect()) + "%").finishMassChanging();
|
||||
}
|
||||
if(last != textInUse)
|
||||
{
|
||||
resize(0F, (textInUse - last) * 5.5F);
|
||||
}
|
||||
else if(lastEmpty)
|
||||
{
|
||||
onChanged(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
if(currentEntry != null && currentEntry.getParent() != null && extraFeatures[0].isHovered(mouseX, mouseY))
|
||||
{
|
||||
setCurrentEntry(currentEntry.getParent().getPathName());
|
||||
}
|
||||
if(lastValues != null)
|
||||
{
|
||||
for(int i = 0;i<textInUse;i++)
|
||||
{
|
||||
TextComponent[] comp = entries.get(i);
|
||||
if(comp[0].isHovered(mouseX, mouseY) || comp[1].isHovered(mouseX, mouseY) || comp[2].isHovered(mouseX, mouseY))
|
||||
{
|
||||
String s = comp[0].getText();
|
||||
s = s.substring(s.indexOf("] ")+2);
|
||||
if(!s.equalsIgnoreCase("Nameless"))
|
||||
{
|
||||
setCurrentEntry(currentEntry.getPathName() + "/" + s);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onClick(button, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptingInput()
|
||||
{
|
||||
return isEnabled() && isVisible() && !isMinimized() && currentEntry != null && hasFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyPressed(int key)
|
||||
{
|
||||
if(key == GLFW.GLFW_KEY_0 && currentEntry != null && currentEntry.getParent() != null)
|
||||
{
|
||||
setCurrentEntry(currentEntry.getParent().getPathName());
|
||||
return true;
|
||||
}
|
||||
else if(key >= GLFW.GLFW_KEY_1 && key <= GLFW.GLFW_KEY_9)
|
||||
{
|
||||
key -= GLFW.GLFW_KEY_1;
|
||||
if(key < textInUse)
|
||||
{
|
||||
String s = entries.get(key)[0].getText();
|
||||
s = s.substring(s.indexOf("] ")+2);
|
||||
if(!s.equalsIgnoreCase("Nameless"))
|
||||
{
|
||||
setCurrentEntry(currentEntry.getPathName() + "/" + s);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2f getMinimumBounds()
|
||||
{
|
||||
return Vec2f.of(80F, 80F + (textInUse * 5.5F));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IPieIndex> get()
|
||||
{
|
||||
if(lastValues != null)
|
||||
{
|
||||
List<IPieIndex> entries = new ObjectArrayList<IPieIndex>();
|
||||
for(int i = 0, m = lastValues.size();i < m;i++)
|
||||
{
|
||||
entries.add(new PieIndex(MathUtils.floor(lastValues.get(i).getEffect() * 1.28D), lastValues.get(i).getColor()));
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
return ObjectLists.singleton(new PieIndex(pie.getMaxSteps(), ColorUtils.LIGHT_BLUE));
|
||||
}
|
||||
|
||||
protected float calculatePieHeight()
|
||||
{
|
||||
return getBox().getBaseHeight() - ((textInUse * 5.5F) + 9F);
|
||||
}
|
||||
|
||||
public IProfiler getProfiler(int index)
|
||||
{
|
||||
GuiManager manager = getGui().getUIManager();
|
||||
switch(index)
|
||||
{
|
||||
case 1:
|
||||
return manager.getGPUProfiler();
|
||||
case 2:
|
||||
return manager.getServerProfiler();
|
||||
default:
|
||||
return manager.getCPUProfiler();
|
||||
}
|
||||
}
|
||||
|
||||
public int getProfilerIndex(IProfiler prof)
|
||||
{
|
||||
GuiManager manager = getGui().getUIManager();
|
||||
return manager.getGPUProfiler() == prof ? 1 : manager.getServerProfiler() == prof ? 2 : 0;
|
||||
}
|
||||
|
||||
public static String getRoot(int index)
|
||||
{
|
||||
return index < 2 ? "Client" : "Server";
|
||||
}
|
||||
|
||||
protected TextComponent createComponent(int column)
|
||||
{
|
||||
final int index = entries.size();
|
||||
String text = column == 0 ? "[" + (entries.size() + 1) + "] Unknown" : PERCENT_FORMAT.format(0D) + "%";
|
||||
TextComponent comp = new TextComponent(0F, 0F, 18F, 5.5F).setTextScale(0.3F).setText(text).align(column == 0 ? Align.LEFT_TOP : Align.RIGHT_BOTTOM, Align.CENTER);
|
||||
comp.addChangeListener(T -> T.setVisible(!isMinimized() && index < textInUse));
|
||||
Constrain xPos = column == 0 ? null : (column == 1 ? new PixelConstrain(38F).setInverted() : new PixelConstrain(19F).setInverted());
|
||||
addChild(comp, new Constrains(xPos, new DynamicConstrain(() -> pie.getBox().getBaseHeight() + (index * 5.5F)), column == 0 ? new PixelConstrain(38).setInverted() : null, null));
|
||||
return comp;
|
||||
}
|
||||
|
||||
protected ButtonComponent createButton(int index, String name)
|
||||
{
|
||||
ButtonComponent button = new ButtonComponent(name, ColorUtils.GRAY);
|
||||
button.getText().setTextScale(0.3F);
|
||||
button.addChangeListener(minimizedListener).addUserActionListener(T -> setProfiler(getProfiler(index), getRoot(index)));
|
||||
addChild(button, new Constrains(new RelativeConstrain(index * 0.3333F), new PixelConstrain(8F).setInverted(), new RelativeConstrain(0.3333F), new PixelConstrain(7F)));
|
||||
return button;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.window.debug;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.collections.objects.utils.ObjectLists;
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.math.misc.Facing;
|
||||
import speiger.src.coreengine.math.vector.floats.Vec2f;
|
||||
import speiger.src.coreengine.rendering.gui.base.IKeyComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.PieComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.PieComponent.IPieIndex;
|
||||
import speiger.src.coreengine.rendering.gui.components.PieComponent.PieIndex;
|
||||
import speiger.src.coreengine.rendering.gui.components.SingleTabPanelComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.Align;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.input.Keyboard;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.ProfilerData;
|
||||
|
||||
public class PieProfilerWindow extends WindowComponent implements Supplier<List<IPieIndex>>, IKeyComponent
|
||||
{
|
||||
public static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("##0.00");
|
||||
|
||||
SingleTabPanelComponent panel = new SingleTabPanelComponent(Facing.SOUTH).onAction(this::onProfilerChanged).cast();
|
||||
PieComponent pie = panel.getPanel().addChild(new PieComponent(127, this).setAutoUpdate(true), Constrains.parent(Target.WIDTH).dynamic(this::calculatePieHeight, Target.HEIGHT).build());
|
||||
TextComponent[] extraFeatures = new TextComponent[] {
|
||||
new TextComponent(0F, 0F, 18F, 7F),
|
||||
new TextComponent(0F, 0F, 0F, 8F),
|
||||
new TextComponent(0F, 8F, 0F, 7F)
|
||||
};
|
||||
List<TextComponent[]> entries = new ObjectArrayList<>();
|
||||
List<ProfilerTab> tabs = new ObjectArrayList<>();
|
||||
int previouseTab = -1;
|
||||
int textInUse = 0;
|
||||
IProfilerEntry currentEntry;
|
||||
String entryName;
|
||||
List<ProfilerData> lastValues = null;
|
||||
|
||||
public PieProfilerWindow(float x, float y, float width, float height, String name)
|
||||
{
|
||||
super(x, y, width, height, DEFAULT_FLAGS, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMoveIntoForground()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
addChild(panel.set(0F, 7.5F).onChange(minimizedListener), Constrains.parent(0.25F, Target.WIDTH).parent(4F, Target.HEIGHT).build());
|
||||
extraFeatures[0].setTextScale(0.3F).setText("[0] Back").horizontal(Align.LEFT_TOP);
|
||||
extraFeatures[0].onChange(T -> T.setVisible(currentEntry != null && currentEntry.getParent() != null));
|
||||
panel.getPanel().addChild(extraFeatures[0], Constrains.dynamic(() -> pie.getBox().getBaseHeight() - 7F, Target.Y).invPixel(38F, Target.WIDTH).build());
|
||||
|
||||
panel.getPanel().addChild(extraFeatures[1].setTextScale(0.4F), Constrains.parent(0F, Target.Y).parent(Target.WIDTH).build());
|
||||
panel.getPanel().addChild(extraFeatures[2].setTextScale(0.33F), Constrains.pixel(8F, Target.Y).parent(Target.WIDTH).build());
|
||||
}
|
||||
|
||||
public PieProfilerWindow addProfiler(IProfiler profiler, String root)
|
||||
{
|
||||
String name = profiler.getName();
|
||||
panel.addTab(name);
|
||||
tabs.add(new ProfilerTab(name, profiler, root));
|
||||
if(tabs.size() == 1)
|
||||
{
|
||||
onProfilerChanged();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
protected IProfiler getActive()
|
||||
{
|
||||
return tabs.get(panel.getActiveIndex()).getProfiler();
|
||||
}
|
||||
|
||||
protected void applyProfiler(boolean prev, Consumer<IProfiler> action)
|
||||
{
|
||||
int index = prev ? previouseTab : panel.getActiveIndex();
|
||||
if(index >= 0) action.accept(tabs.get(index).getProfiler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosed()
|
||||
{
|
||||
super.onClosed();
|
||||
applyProfiler(false, IProfiler::disable);
|
||||
}
|
||||
|
||||
protected void onProfilerChanged()
|
||||
{
|
||||
if(previouseTab == panel.getActiveIndex()) return;
|
||||
applyProfiler(true, IProfiler::disable);
|
||||
applyProfiler(false, IProfiler::enable);
|
||||
previouseTab = panel.getActiveIndex();
|
||||
ProfilerTab tab = tabs.get(previouseTab);
|
||||
extraFeatures[1].setText(tab.getName());
|
||||
setCurrentEntry(tab.getRoot());
|
||||
}
|
||||
|
||||
public SingleTabPanelComponent getTab()
|
||||
{
|
||||
return panel;
|
||||
}
|
||||
|
||||
public PieProfilerWindow setCurrentEntry(String name)
|
||||
{
|
||||
entryName = name;
|
||||
currentEntry = getActive().getEntry(name);
|
||||
lastValues = null;
|
||||
extraFeatures[2].setText(currentEntry == null ? "Unknown" : currentEntry.getName());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
||||
{
|
||||
for(int i = 0,m=entries.size();i<m;i++)
|
||||
{
|
||||
TextComponent[] comp = entries.get(i);
|
||||
float brightness = comp[0].isTopHovered(mouseX, mouseY) || comp[1].isTopHovered(mouseX, mouseY) || comp[2].isTopHovered(mouseX, mouseY) ? 0.7F : 1F;
|
||||
comp[0].setBrightness(brightness);
|
||||
comp[1].setBrightness(brightness);
|
||||
comp[2].setBrightness(brightness);
|
||||
}
|
||||
extraFeatures[0].setBrightness(extraFeatures[0].isHovered(mouseX, mouseY) ? 0.7F : 1F);
|
||||
return super.updateSelf(mouseX, mouseY, particalTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fixedUpdateSelf()
|
||||
{
|
||||
if(panel.getActiveIndex() < 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(currentEntry == null)
|
||||
{
|
||||
setCurrentEntry(entryName);
|
||||
return true;
|
||||
}
|
||||
if(currentEntry.getNanoTime() == 0L || (Keyboard.isAltDown() && lastValues != null) || (lastValues != null && getGlobalClock() % 2 != 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
while(entries.size() < currentEntry.getChildCount() + 1)
|
||||
{
|
||||
entries.add(new TextComponent[] {createComponent(0), createComponent(1), createComponent(2) });
|
||||
}
|
||||
boolean lastEmpty = lastValues == null;
|
||||
lastValues = currentEntry.getData();
|
||||
int last = textInUse;
|
||||
textInUse = lastValues.size();
|
||||
for(int i = 0;i < textInUse;i++)
|
||||
{
|
||||
ProfilerData data = lastValues.get(i);
|
||||
TextComponent[] info = entries.get(i);
|
||||
int color = data.getColor();
|
||||
info[0].setMassChanging(TextComponent.class).textColor(color).setText("[" + (i + 1) + "] " + data.getName()).finishMassChanging();
|
||||
info[1].setMassChanging(TextComponent.class).textColor(color).setText(PERCENT_FORMAT.format(data.getEffect()) + "%").finishMassChanging();
|
||||
info[2].setMassChanging(TextComponent.class).textColor(color).setText(PERCENT_FORMAT.format(data.getTotalEffect()) + "%").finishMassChanging();
|
||||
}
|
||||
if(last != textInUse)
|
||||
{
|
||||
float diff = 80F + (textInUse * 7F) - this.getBox().getHeight();
|
||||
if(diff > 0) {
|
||||
resize(0F, diff);
|
||||
}
|
||||
onChanged(true);
|
||||
}
|
||||
else if(lastEmpty)
|
||||
{
|
||||
onChanged(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button, int mouseX, int mouseY)
|
||||
{
|
||||
if(super.onClick(button, mouseX, mouseY))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(currentEntry != null && currentEntry.getParent() != null && extraFeatures[0].isHovered(mouseX, mouseY))
|
||||
{
|
||||
setCurrentEntry(currentEntry.getParent().getPathName());
|
||||
}
|
||||
if(lastValues != null)
|
||||
{
|
||||
for(int i = 0;i<textInUse;i++)
|
||||
{
|
||||
TextComponent[] comp = entries.get(i);
|
||||
if(comp[0].isHovered(mouseX, mouseY) || comp[1].isHovered(mouseX, mouseY) || comp[2].isHovered(mouseX, mouseY))
|
||||
{
|
||||
String s = comp[0].getText();
|
||||
s = s.substring(s.indexOf("] ")+2);
|
||||
if(!s.equalsIgnoreCase("Nameless"))
|
||||
{
|
||||
setCurrentEntry(currentEntry.getPathName() + "/" + s);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptingInput()
|
||||
{
|
||||
return isEnabled() && isVisible() && !isMinimized() && currentEntry != null && hasFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyPressed(int key)
|
||||
{
|
||||
if(key == GLFW.GLFW_KEY_0 && currentEntry != null && currentEntry.getParent() != null)
|
||||
{
|
||||
setCurrentEntry(currentEntry.getParent().getPathName());
|
||||
return true;
|
||||
}
|
||||
else if(key >= GLFW.GLFW_KEY_1 && key <= GLFW.GLFW_KEY_9)
|
||||
{
|
||||
key -= GLFW.GLFW_KEY_1;
|
||||
if(key < textInUse)
|
||||
{
|
||||
String s = entries.get(key)[0].getText();
|
||||
s = s.substring(s.indexOf("] ")+2);
|
||||
if(!s.equalsIgnoreCase("Nameless"))
|
||||
{
|
||||
setCurrentEntry(currentEntry.getPathName() + "/" + s);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2f getMinimumBounds()
|
||||
{
|
||||
return Vec2f.of(80F, 80F + (textInUse * 7F));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IPieIndex> get()
|
||||
{
|
||||
if(lastValues != null)
|
||||
{
|
||||
List<IPieIndex> entries = new ObjectArrayList<>();
|
||||
for(int i = 0, m = lastValues.size();i < m;i++)
|
||||
{
|
||||
entries.add(new PieIndex(MathUtils.floor(lastValues.get(i).getEffect() * 1.28D), lastValues.get(i).getColor()));
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
return ObjectLists.singleton(new PieIndex(pie.getMaxSteps(), ColorUtils.LIGHT_BLUE));
|
||||
}
|
||||
|
||||
protected float calculatePieHeight()
|
||||
{
|
||||
return getBox().getBaseHeight() - ((textInUse * 7) + 17F);
|
||||
}
|
||||
|
||||
protected TextComponent createComponent(int column)
|
||||
{
|
||||
final int index = entries.size();
|
||||
String text = column == 0 ? "[" + (entries.size() + 1) + "] Unknown" : PERCENT_FORMAT.format(0D) + "%";
|
||||
TextComponent comp = new TextComponent(0F, 0F, 18F, 7F).setTextScale(0.33F).setText(text).align(column == 0 ? Align.LEFT_TOP : Align.RIGHT_BOTTOM, Align.CENTER);
|
||||
comp.onChange(T -> T.setVisible(index < textInUse));
|
||||
Constrain xPos = column == 0 ? null : (column == 1 ? new PixelConstrain(38F).setInverted() : new PixelConstrain(19F).setInverted());
|
||||
panel.getPanel().addChild(comp, new Constrains(xPos, new DynamicConstrain(() -> pie.getBox().getBaseHeight() + (index * 7F)), column == 0 ? new PixelConstrain(38).setInverted() : null, null));
|
||||
return comp;
|
||||
}
|
||||
|
||||
private static class ProfilerTab
|
||||
{
|
||||
String name;
|
||||
IProfiler profiler;
|
||||
String root;
|
||||
|
||||
public ProfilerTab(String name, IProfiler profiler, String root)
|
||||
{
|
||||
this.name = name;
|
||||
this.profiler = profiler;
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public IProfiler getProfiler()
|
||||
{
|
||||
return profiler;
|
||||
}
|
||||
|
||||
public String getRoot()
|
||||
{
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -1,60 +1,60 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.window.misc;
|
||||
|
||||
import speiger.src.collections.booleans.functions.BooleanConsumer;
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
|
||||
|
||||
public class ChoiceComponent extends WindowComponent
|
||||
{
|
||||
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
|
||||
ButtonComponent yesButton = new ButtonComponent("Yes", ColorUtils.GRAY);
|
||||
ButtonComponent noButton = new ButtonComponent("No", ColorUtils.GRAY);
|
||||
BooleanConsumer listener;
|
||||
|
||||
public ChoiceComponent(float width, String windowTitle, String message, BooleanConsumer listener)
|
||||
{
|
||||
this(0F, 0F, width, windowTitle, message, listener);
|
||||
}
|
||||
|
||||
public ChoiceComponent(float x, float y, float width, String windowTitle, String message, BooleanConsumer listener)
|
||||
{
|
||||
super(x, y, width, 25F, FIXED_SIZE_POPUP, windowTitle);
|
||||
this.message.setText(message);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public static ChoiceComponent createChoice(float width, String windowTitle, String message, BooleanConsumer listener)
|
||||
{
|
||||
return new ChoiceComponent(width, windowTitle, message, listener);
|
||||
}
|
||||
|
||||
public static ChoiceComponent createChoice(String windowTitle, String message, BooleanConsumer listener)
|
||||
{
|
||||
return new ChoiceComponent(150, windowTitle, message, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
yesButton.getText().setTextScale(0.5F);
|
||||
noButton.getText().setTextScale(0.5F);
|
||||
addChild(yesButton.addChangeListener(minimizedListener).addUserActionListener(closeListener).addUserActionListener(T -> listener.accept(true)), new Constrains(new RelativeConstrain(0F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F)));
|
||||
addChild(noButton.addChangeListener(minimizedListener).addUserActionListener(closeListener).addUserActionListener(T -> listener.accept(false)), new Constrains(new RelativeConstrain(0.5F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F)));
|
||||
addChild(message, new Constrains(new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message)));
|
||||
getBox().setHeight(25F + message.getMetadata().getMaxHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPopup()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.window.misc;
|
||||
|
||||
import speiger.src.collections.booleans.functions.BooleanConsumer;
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
|
||||
|
||||
public class ChoiceComponent extends WindowComponent
|
||||
{
|
||||
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
|
||||
ButtonComponent yesButton = new ButtonComponent("Yes", ColorUtils.GRAY);
|
||||
ButtonComponent noButton = new ButtonComponent("No", ColorUtils.GRAY);
|
||||
BooleanConsumer listener;
|
||||
|
||||
public ChoiceComponent(float width, String windowTitle, String message, BooleanConsumer listener)
|
||||
{
|
||||
this(0F, 0F, width, windowTitle, message, listener);
|
||||
}
|
||||
|
||||
public ChoiceComponent(float x, float y, float width, String windowTitle, String message, BooleanConsumer listener)
|
||||
{
|
||||
super(x, y, width, 25F, FIXED_SIZE_POPUP, windowTitle);
|
||||
this.message.setText(message);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public static ChoiceComponent createChoice(float width, String windowTitle, String message, BooleanConsumer listener)
|
||||
{
|
||||
return new ChoiceComponent(width, windowTitle, message, listener);
|
||||
}
|
||||
|
||||
public static ChoiceComponent createChoice(String windowTitle, String message, BooleanConsumer listener)
|
||||
{
|
||||
return new ChoiceComponent(150, windowTitle, message, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
yesButton.getText().setTextScale(0.5F);
|
||||
noButton.getText().setTextScale(0.5F);
|
||||
addChild(yesButton.onChange(minimizedListener).onAction(closeListener).onAction(T -> listener.accept(true)), new Constrains(new RelativeConstrain(0F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F)));
|
||||
addChild(noButton.onChange(minimizedListener).onAction(closeListener).onAction(T -> listener.accept(false)), new Constrains(new RelativeConstrain(0.5F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F)));
|
||||
addChild(message, new Constrains(new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message)));
|
||||
getBox().setHeight(25F + message.getMetadata().getMaxHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPopup()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,74 +1,74 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.window.misc;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
|
||||
|
||||
public class MessageComponent extends WindowComponent
|
||||
{
|
||||
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
|
||||
ButtonComponent resultButton = new ButtonComponent("", ColorUtils.GRAY);
|
||||
|
||||
public MessageComponent(float width, String windowTitle, String confirmButton, String message)
|
||||
{
|
||||
this(0F, 0F, width, windowTitle, confirmButton, message);
|
||||
}
|
||||
|
||||
public MessageComponent(float x, float y, float width, String windowTitle, String confirmButton, String message)
|
||||
{
|
||||
super(x, y, width, 25F, FIXED_SIZE_POPUP, windowTitle);
|
||||
resultButton.getText().setText(confirmButton);
|
||||
this.message.setText(message);
|
||||
}
|
||||
|
||||
public static MessageComponent createInfo(String message)
|
||||
{
|
||||
return new MessageComponent(150, "Info", "Ok", message);
|
||||
}
|
||||
|
||||
public static MessageComponent createInfo(float width, String message)
|
||||
{
|
||||
return new MessageComponent(width, "Info", "Ok", message);
|
||||
}
|
||||
|
||||
public static MessageComponent createWarn(String message)
|
||||
{
|
||||
return new MessageComponent(150, "Warn", "Ok", message);
|
||||
}
|
||||
|
||||
public static MessageComponent createWarn(float width, String message)
|
||||
{
|
||||
return new MessageComponent(width, "Warn", "Ok", message);
|
||||
}
|
||||
|
||||
public static MessageComponent createError(String message)
|
||||
{
|
||||
return new MessageComponent(150, "Error!", "Ok", message);
|
||||
}
|
||||
|
||||
public static MessageComponent createError(float width, String message)
|
||||
{
|
||||
return new MessageComponent(width, "Error!", "Ok", message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
resultButton.getText().setTextScale(0.5F);
|
||||
addChild(resultButton.addChangeListener(minimizedListener).addUserActionListener(closeListener), new Constrains(new ParentConstrain(), new ParentConstrain(10F).invert(), new ParentConstrain(), new PixelConstrain(10F)));
|
||||
addChild(message, new Constrains(new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message)));
|
||||
getBox().setHeight(25F + message.getMetadata().getMaxHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPopup()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.window.misc;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
|
||||
|
||||
public class MessageComponent extends WindowComponent
|
||||
{
|
||||
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
|
||||
ButtonComponent resultButton = new ButtonComponent("", ColorUtils.GRAY);
|
||||
|
||||
public MessageComponent(float width, String windowTitle, String confirmButton, String message)
|
||||
{
|
||||
this(0F, 0F, width, windowTitle, confirmButton, message);
|
||||
}
|
||||
|
||||
public MessageComponent(float x, float y, float width, String windowTitle, String confirmButton, String message)
|
||||
{
|
||||
super(x, y, width, 25F, FIXED_SIZE_POPUP, windowTitle);
|
||||
resultButton.getText().setText(confirmButton);
|
||||
this.message.setText(message);
|
||||
}
|
||||
|
||||
public static MessageComponent createInfo(String message)
|
||||
{
|
||||
return new MessageComponent(150, "Info", "Ok", message);
|
||||
}
|
||||
|
||||
public static MessageComponent createInfo(float width, String message)
|
||||
{
|
||||
return new MessageComponent(width, "Info", "Ok", message);
|
||||
}
|
||||
|
||||
public static MessageComponent createWarn(String message)
|
||||
{
|
||||
return new MessageComponent(150, "Warn", "Ok", message);
|
||||
}
|
||||
|
||||
public static MessageComponent createWarn(float width, String message)
|
||||
{
|
||||
return new MessageComponent(width, "Warn", "Ok", message);
|
||||
}
|
||||
|
||||
public static MessageComponent createError(String message)
|
||||
{
|
||||
return new MessageComponent(150, "Error!", "Ok", message);
|
||||
}
|
||||
|
||||
public static MessageComponent createError(float width, String message)
|
||||
{
|
||||
return new MessageComponent(width, "Error!", "Ok", message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
resultButton.getText().setTextScale(0.5F);
|
||||
addChild(resultButton.onChange(minimizedListener).onAction(closeListener), new Constrains(new ParentConstrain(), new ParentConstrain(10F).invert(), new ParentConstrain(), new PixelConstrain(10F)));
|
||||
addChild(message, new Constrains(new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message)));
|
||||
getBox().setHeight(25F + message.getMetadata().getMaxHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPopup()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
package speiger.src.coreengine.rendering.gui.components.window.misc;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
|
||||
|
||||
public class TextInputComponent extends WindowComponent
|
||||
{
|
||||
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
|
||||
TextFieldComponent input = new TextFieldComponent(ColorUtils.GRAY).setCanLoseFocus(false).setInfiniteText(true).setMaxTextLength(Integer.MAX_VALUE).setFocused(true);
|
||||
ButtonComponent confirm = new ButtonComponent("Confirm", ColorUtils.DARK_GREEN);
|
||||
ButtonComponent cancel = new ButtonComponent("Cancel", ColorUtils.RED);
|
||||
|
||||
public TextInputComponent(float width, String name, String message)
|
||||
{
|
||||
this(0F, 0F, width, name, message);
|
||||
}
|
||||
|
||||
public TextInputComponent(float x, float y, float width, String name, String message)
|
||||
{
|
||||
super(x, y, width, 35F, FIXED_SIZE_POPUP, name);
|
||||
this.message.setText(message);
|
||||
}
|
||||
|
||||
public TextFieldComponent getInput()
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
public String getText()
|
||||
{
|
||||
return input.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
confirm.getText().setTextScale(0.5F);
|
||||
cancel.getText().setTextScale(0.5F);
|
||||
input.getRawText().setTextScale(0.5F);
|
||||
addChild(confirm.addChangeListener(minimizedListener).addUserActionListener(this::onListen), new RelativeConstrain(0F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F));
|
||||
addChild(cancel.addChangeListener(minimizedListener).addUserActionListener(closeListener), new RelativeConstrain(0.5F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F));
|
||||
addChild(message.addChangeListener(minimizedListener), new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message));
|
||||
addChild(input.addChangeListener(minimizedListener).addUserActionListener(this::onListen), new PixelConstrain(10F), TextConstrain.height(message).setPadding(15F), new ParentConstrain(10F), new PixelConstrain(12F));
|
||||
getBox().setHeight(45F + message.getMetadata().getMaxHeight());
|
||||
}
|
||||
|
||||
private void onListen()
|
||||
{
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
closeListener.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPopup()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.components.window.misc;
|
||||
|
||||
import speiger.src.coreengine.math.misc.ColorUtils;
|
||||
import speiger.src.coreengine.rendering.gui.components.ButtonComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextFieldComponent;
|
||||
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.ParentConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.RelativeConstrain;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.TextConstrain;
|
||||
|
||||
public class TextInputComponent extends WindowComponent
|
||||
{
|
||||
TextComponent message = new TextComponent().limitHeight(false).setTextScale(0.5F);
|
||||
TextFieldComponent input = new TextFieldComponent(ColorUtils.GRAY).setCanLoseFocus(false).setInfiniteText(true).setMaxTextLength(Integer.MAX_VALUE).setFocused(true);
|
||||
ButtonComponent confirm = new ButtonComponent("Confirm", ColorUtils.DARK_GREEN);
|
||||
ButtonComponent cancel = new ButtonComponent("Cancel", ColorUtils.RED);
|
||||
|
||||
public TextInputComponent(float width, String name, String message)
|
||||
{
|
||||
this(0F, 0F, width, name, message);
|
||||
}
|
||||
|
||||
public TextInputComponent(float x, float y, float width, String name, String message)
|
||||
{
|
||||
super(x, y, width, 35F, FIXED_SIZE_POPUP, name);
|
||||
this.message.setText(message);
|
||||
}
|
||||
|
||||
public TextFieldComponent getInput()
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
public String getText()
|
||||
{
|
||||
return input.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
confirm.getText().setTextScale(0.5F);
|
||||
cancel.getText().setTextScale(0.5F);
|
||||
input.getRawText().setTextScale(0.5F);
|
||||
addChild(confirm.onChange(minimizedListener).onAction(this::onListen), new RelativeConstrain(0F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F));
|
||||
addChild(cancel.onChange(minimizedListener).onAction(closeListener), new RelativeConstrain(0.5F), new ParentConstrain(10F).invert(), new RelativeConstrain(0.5F), new PixelConstrain(10F));
|
||||
addChild(message.onChange(minimizedListener), new PixelConstrain(10F), new PixelConstrain(11F), new ParentConstrain(10F), TextConstrain.height(message));
|
||||
addChild(input.onChange(minimizedListener).onAction(this::onListen), new PixelConstrain(10F), TextConstrain.height(message).setPadding(15F), new ParentConstrain(10F), new PixelConstrain(12F));
|
||||
getBox().setHeight(45F + message.getMetadata().getMaxHeight());
|
||||
}
|
||||
|
||||
private void onListen()
|
||||
{
|
||||
notifyListeners(LISTENER_USER_ACTION);
|
||||
closeListener.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPopup()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
package speiger.src.coreengine.rendering.gui.helper.animations;
|
||||
|
||||
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
|
||||
import speiger.src.collections.objects.utils.maps.Object2ObjectMaps;
|
||||
import speiger.src.coreengine.math.value.ConstantValue;
|
||||
import speiger.src.coreengine.math.value.IValue;
|
||||
import speiger.src.coreengine.rendering.gui.helper.animations.Animation.AnimationListener;
|
||||
|
||||
public class AnimationInstance
|
||||
{
|
||||
Object2ObjectMap<AnimationTarget, IValue> values;
|
||||
float totalProgress;
|
||||
boolean reverse;
|
||||
AnimationListener listener;
|
||||
float progress = 0F;
|
||||
|
||||
public AnimationInstance(Object2ObjectMap<AnimationTarget, IValue> values, float totalProgress, boolean reverse, AnimationListener listener)
|
||||
{
|
||||
this.values = values;
|
||||
this.totalProgress = totalProgress;
|
||||
this.reverse = reverse;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void update(Animator animator, float particalTime)
|
||||
{
|
||||
progress += particalTime;
|
||||
for(Object2ObjectMap.Entry<AnimationTarget, IValue> entry : Object2ObjectMaps.fastIterable(values))
|
||||
{
|
||||
entry.getKey().apply(animator, entry.getValue().update(particalTime));
|
||||
}
|
||||
}
|
||||
|
||||
public float getCurrentProgress(AnimationTarget target)
|
||||
{
|
||||
return values.getOrDefault(target, ConstantValue.ZERO).get();
|
||||
}
|
||||
|
||||
public boolean isDone()
|
||||
{
|
||||
return reverse && progress >= totalProgress;
|
||||
}
|
||||
|
||||
public AnimationListener getListener()
|
||||
{
|
||||
return listener;
|
||||
}
|
||||
|
||||
public boolean isReverse()
|
||||
{
|
||||
return reverse;
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.helper.animations;
|
||||
|
||||
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
|
||||
import speiger.src.collections.objects.utils.maps.Object2ObjectMaps;
|
||||
import speiger.src.coreengine.math.value.ConstantValue;
|
||||
import speiger.src.coreengine.math.value.IValue;
|
||||
import speiger.src.coreengine.rendering.gui.helper.animations.Animation.AnimationListener;
|
||||
|
||||
public class AnimationInstance
|
||||
{
|
||||
Object2ObjectMap<AnimationTarget, IValue> values;
|
||||
float totalProgress;
|
||||
boolean reverse;
|
||||
AnimationListener listener;
|
||||
float progress = 0F;
|
||||
|
||||
public AnimationInstance(Object2ObjectMap<AnimationTarget, IValue> values, float totalProgress, boolean reverse, AnimationListener listener)
|
||||
{
|
||||
this.values = values;
|
||||
this.totalProgress = totalProgress;
|
||||
this.reverse = reverse;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void update(Animator animator, float particalTime)
|
||||
{
|
||||
progress += particalTime;
|
||||
for(Object2ObjectMap.Entry<AnimationTarget, IValue> entry : Object2ObjectMaps.fastIterable(values))
|
||||
{
|
||||
entry.getKey().apply(animator, entry.getValue().update(particalTime));
|
||||
}
|
||||
}
|
||||
|
||||
public float getCurrentProgress(AnimationTarget target)
|
||||
{
|
||||
return values.getOrDefault(target, ConstantValue.ZERO).get();
|
||||
}
|
||||
|
||||
public boolean isDone()
|
||||
{
|
||||
return reverse && progress >= totalProgress;
|
||||
}
|
||||
|
||||
public AnimationListener getListener()
|
||||
{
|
||||
return listener;
|
||||
}
|
||||
|
||||
public boolean isReverse()
|
||||
{
|
||||
return reverse;
|
||||
}
|
||||
}
|
|
@ -1,125 +1,131 @@
|
|||
package speiger.src.coreengine.rendering.gui.helper.constrains;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
import speiger.src.coreengine.math.misc.Facing;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
|
||||
import speiger.src.coreengine.utils.functions.FloatSupplier;
|
||||
|
||||
public class Constrains
|
||||
{
|
||||
Constrain[] constrains = new Constrain[4];
|
||||
|
||||
private Constrains(Constrain[] array)
|
||||
{
|
||||
System.arraycopy(array, 0, constrains, 0, 4);
|
||||
}
|
||||
|
||||
public Constrains(Constrain xPos, Constrain yPos, Constrain width, Constrain height)
|
||||
{
|
||||
constrains[0] = xPos;
|
||||
constrains[1] = yPos;
|
||||
constrains[2] = width;
|
||||
constrains[3] = height;
|
||||
}
|
||||
|
||||
public void setOwner(GuiComponent owner, GuiComponent parent)
|
||||
{
|
||||
for(int i = 0;i<4;i++) {
|
||||
if(constrains[i] != null) {
|
||||
constrains[i].setComponents(owner, parent, Target.by(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onComponentChanged()
|
||||
{
|
||||
for(int i = 0;i<4;i++) {
|
||||
if(constrains[i] != null) constrains[i].apply();
|
||||
}
|
||||
}
|
||||
|
||||
public static Constrains parent() { return new Constrains(new ParentConstrain(), new ParentConstrain(), new ParentConstrain(), new ParentConstrain()); }
|
||||
public static Constrains parent(float padding) { return new Constrains(new ParentConstrain(padding), new ParentConstrain(padding), new ParentConstrain(padding), new ParentConstrain(padding)); }
|
||||
public static Constrains parent(float xPadding, float yPadding) { return new Constrains(new ParentConstrain(xPadding), new ParentConstrain(yPadding), new ParentConstrain(xPadding), new ParentConstrain(yPadding)); }
|
||||
public static Constrains parent(float x, float y, float width, float height) { return new Constrains(new ParentConstrain(x), new ParentConstrain(y), new ParentConstrain(width), new ParentConstrain(height)); }
|
||||
|
||||
public static Constrains scrollBar(BooleanSupplier supply, boolean horizontal, float barSize) {
|
||||
Constrain bounds = new ConditionalConstraint(supply, new ParentConstrain(), new ParentConstrain(barSize / 2F));
|
||||
return horizontal ? new Constrains(new PixelConstrain(), new ParentConstrain(barSize).invert(), bounds, new PixelConstrain(barSize)) : new Constrains(new ParentConstrain(barSize).invert(), new PixelConstrain(), new PixelConstrain(barSize), bounds);
|
||||
}
|
||||
|
||||
public static Constrains verticalScrollBar(BooleanSupplier supply, float offset, float barSize) { return invParent(barSize, Target.X).yPos(offset).width(barSize).height(new ConditionalConstraint(supply, new ParentConstrain(offset * 0.5F), new ParentConstrain((barSize + offset) * 0.5F))).build(); }
|
||||
|
||||
public static Constrains border(float size, Facing side, float offset)
|
||||
{
|
||||
switch(side)
|
||||
{
|
||||
case NORTH: return new Constrains(new ParentConstrain(), new ParentConstrain(offset), new ParentConstrain(), new PixelConstrain(size));
|
||||
case EAST: return new Constrains(new ParentConstrain(size+offset).invert(), new ParentConstrain(), new PixelConstrain(size), new ParentConstrain());
|
||||
case SOUTH: return new Constrains(new ParentConstrain(), new ParentConstrain(size+offset).invert(), new ParentConstrain(), new PixelConstrain(size));
|
||||
case WEST: return new Constrains(new ParentConstrain(offset), new ParentConstrain(), new PixelConstrain(size), new ParentConstrain());
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ConstrainBuilder xPos(Constrain xPos) { return new ConstrainBuilder().set(xPos, Target.X); }
|
||||
public static ConstrainBuilder yPos(Constrain yPos) { return new ConstrainBuilder().set(yPos, Target.Y); }
|
||||
public static ConstrainBuilder width(Constrain width) { return new ConstrainBuilder().set(width, Target.WIDTH); }
|
||||
public static ConstrainBuilder height(Constrain height) { return new ConstrainBuilder().set(height, Target.HEIGHT); }
|
||||
|
||||
public static ConstrainBuilder xPos(float xPos) { return new ConstrainBuilder().set(new PixelConstrain(xPos), Target.X); }
|
||||
public static ConstrainBuilder yPos(float yPos) { return new ConstrainBuilder().set(new PixelConstrain(yPos), Target.Y); }
|
||||
public static ConstrainBuilder width(float width) { return new ConstrainBuilder().set(new PixelConstrain(width), Target.WIDTH); }
|
||||
public static ConstrainBuilder height(float height) { return new ConstrainBuilder().set(new PixelConstrain(height), Target.HEIGHT); }
|
||||
|
||||
public static ConstrainBuilder xPosR(float xPos) { return new ConstrainBuilder().set(new RelativeConstrain(xPos), Target.X); }
|
||||
public static ConstrainBuilder yPosR(float yPos) { return new ConstrainBuilder().set(new RelativeConstrain(yPos), Target.Y); }
|
||||
public static ConstrainBuilder widthR(float width) { return new ConstrainBuilder().set(new RelativeConstrain(width), Target.WIDTH); }
|
||||
public static ConstrainBuilder heightR(float height) { return new ConstrainBuilder().set(new RelativeConstrain(height), Target.HEIGHT); }
|
||||
|
||||
public static ConstrainBuilder parent(Target target) { return new ConstrainBuilder().set(new ParentConstrain(), target); }
|
||||
public static ConstrainBuilder invParent(Target target) { return new ConstrainBuilder().set(new ParentConstrain().invert(), target); }
|
||||
public static ConstrainBuilder parent(float padding, Target target) { return new ConstrainBuilder().set(new ParentConstrain(padding), target); }
|
||||
public static ConstrainBuilder invParent(float padding, Target target) { return new ConstrainBuilder().set(new ParentConstrain(padding).invert(), target); }
|
||||
public static ConstrainBuilder center(Target target) { return new ConstrainBuilder().set(new CenterConstrain(), target); }
|
||||
public static ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return new ConstrainBuilder().set(new DynamicConstrain(provider), target); }
|
||||
|
||||
public static class ConstrainBuilder
|
||||
{
|
||||
Constrain[] constrains = new Constrain[4];
|
||||
|
||||
public ConstrainBuilder set(Constrain value, Target target) {
|
||||
constrains[target.ordinal()] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConstrainBuilder xPos(Constrain xPos) { return set(xPos, Target.X); }
|
||||
public ConstrainBuilder yPos(Constrain yPos) { return set(yPos, Target.Y); }
|
||||
public ConstrainBuilder width(Constrain width) { return set(width, Target.WIDTH); }
|
||||
public ConstrainBuilder height(Constrain height) { return set(height, Target.HEIGHT); }
|
||||
|
||||
public ConstrainBuilder xPos(float xPos) { return set(new PixelConstrain(xPos), Target.X); }
|
||||
public ConstrainBuilder yPos(float yPos) { return set(new PixelConstrain(yPos), Target.Y); }
|
||||
public ConstrainBuilder width(float width) { return set(new PixelConstrain(width), Target.WIDTH); }
|
||||
public ConstrainBuilder height(float height) { return set(new PixelConstrain(height), Target.HEIGHT); }
|
||||
|
||||
public ConstrainBuilder xPosR(float xPos) { return set(new RelativeConstrain(xPos), Target.X); }
|
||||
public ConstrainBuilder yPosR(float yPos) { return set(new RelativeConstrain(yPos), Target.Y); }
|
||||
public ConstrainBuilder widthR(float width) { return set(new RelativeConstrain(width), Target.WIDTH); }
|
||||
public ConstrainBuilder heightR(float height) { return set(new RelativeConstrain(height), Target.HEIGHT); }
|
||||
|
||||
public ConstrainBuilder parent(Target target) { return set(new ParentConstrain(), target); }
|
||||
public ConstrainBuilder invParent(Target target) { return set(new ParentConstrain().invert(), target); }
|
||||
public ConstrainBuilder parent(float padding, Target target) { return set(new ParentConstrain(padding), target); }
|
||||
public ConstrainBuilder invParent(float padding, Target target) { return set(new ParentConstrain(padding).invert(), target); }
|
||||
public ConstrainBuilder center(Target target) { return set(new CenterConstrain(), target); }
|
||||
public ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return set(new DynamicConstrain(provider), target); }
|
||||
|
||||
public Constrains build()
|
||||
{
|
||||
return new Constrains(constrains);
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.helper.constrains;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
import speiger.src.coreengine.math.misc.Facing;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
|
||||
import speiger.src.coreengine.utils.functions.FloatSupplier;
|
||||
|
||||
public class Constrains
|
||||
{
|
||||
Constrain[] constrains = new Constrain[4];
|
||||
|
||||
private Constrains(Constrain[] array)
|
||||
{
|
||||
System.arraycopy(array, 0, constrains, 0, 4);
|
||||
}
|
||||
|
||||
public Constrains(Constrain xPos, Constrain yPos, Constrain width, Constrain height)
|
||||
{
|
||||
constrains[0] = xPos;
|
||||
constrains[1] = yPos;
|
||||
constrains[2] = width;
|
||||
constrains[3] = height;
|
||||
}
|
||||
|
||||
public void setOwner(GuiComponent owner, GuiComponent parent)
|
||||
{
|
||||
for(int i = 0;i<4;i++) {
|
||||
if(constrains[i] != null) {
|
||||
constrains[i].setComponents(owner, parent, Target.by(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onComponentChanged()
|
||||
{
|
||||
for(int i = 0;i<4;i++) {
|
||||
if(constrains[i] != null) constrains[i].apply();
|
||||
}
|
||||
}
|
||||
|
||||
public static Constrains parent() { return new Constrains(new ParentConstrain(), new ParentConstrain(), new ParentConstrain(), new ParentConstrain()); }
|
||||
public static Constrains parent(float padding) { return new Constrains(new ParentConstrain(padding), new ParentConstrain(padding), new ParentConstrain(padding), new ParentConstrain(padding)); }
|
||||
public static Constrains parent(float xPadding, float yPadding) { return new Constrains(new ParentConstrain(xPadding), new ParentConstrain(yPadding), new ParentConstrain(xPadding), new ParentConstrain(yPadding)); }
|
||||
public static Constrains parent(float x, float y, float width, float height) { return new Constrains(new ParentConstrain(x), new ParentConstrain(y), new ParentConstrain(width), new ParentConstrain(height)); }
|
||||
|
||||
public static Constrains scrollBar(BooleanSupplier supply, boolean horizontal, float barSize) {
|
||||
Constrain bounds = new ConditionalConstraint(supply, new ParentConstrain(), new ParentConstrain(barSize / 2F));
|
||||
return horizontal ? new Constrains(new PixelConstrain(), new ParentConstrain(barSize).invert(), bounds, new PixelConstrain(barSize)) : new Constrains(new ParentConstrain(barSize).invert(), new PixelConstrain(), new PixelConstrain(barSize), bounds);
|
||||
}
|
||||
|
||||
public static Constrains verticalScrollBar(BooleanSupplier supply, float offset, float barSize) { return invParent(barSize, Target.X).yPos(offset).width(barSize).height(new ConditionalConstraint(supply, new ParentConstrain(offset * 0.5F), new ParentConstrain((barSize + offset) * 0.5F))).build(); }
|
||||
|
||||
public static Constrains border(float size, Facing side, float offset)
|
||||
{
|
||||
switch(side)
|
||||
{
|
||||
case NORTH: return new Constrains(new ParentConstrain(), new ParentConstrain(offset), new ParentConstrain(), new PixelConstrain(size));
|
||||
case EAST: return new Constrains(new ParentConstrain(size+offset).invert(), new ParentConstrain(), new PixelConstrain(size), new ParentConstrain());
|
||||
case SOUTH: return new Constrains(new ParentConstrain(), new ParentConstrain(size+offset).invert(), new ParentConstrain(), new PixelConstrain(size));
|
||||
case WEST: return new Constrains(new ParentConstrain(offset), new ParentConstrain(), new PixelConstrain(size), new ParentConstrain());
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ConstrainBuilder builder() { return new ConstrainBuilder(); };
|
||||
|
||||
public static ConstrainBuilder xPos(Constrain xPos) { return new ConstrainBuilder().set(xPos, Target.X); }
|
||||
public static ConstrainBuilder yPos(Constrain yPos) { return new ConstrainBuilder().set(yPos, Target.Y); }
|
||||
public static ConstrainBuilder width(Constrain width) { return new ConstrainBuilder().set(width, Target.WIDTH); }
|
||||
public static ConstrainBuilder height(Constrain height) { return new ConstrainBuilder().set(height, Target.HEIGHT); }
|
||||
|
||||
public static ConstrainBuilder xPos(float xPos) { return new ConstrainBuilder().set(new PixelConstrain(xPos), Target.X); }
|
||||
public static ConstrainBuilder yPos(float yPos) { return new ConstrainBuilder().set(new PixelConstrain(yPos), Target.Y); }
|
||||
public static ConstrainBuilder width(float width) { return new ConstrainBuilder().set(new PixelConstrain(width), Target.WIDTH); }
|
||||
public static ConstrainBuilder height(float height) { return new ConstrainBuilder().set(new PixelConstrain(height), Target.HEIGHT); }
|
||||
|
||||
public static ConstrainBuilder xPosR(float xPos) { return new ConstrainBuilder().set(new RelativeConstrain(xPos), Target.X); }
|
||||
public static ConstrainBuilder yPosR(float yPos) { return new ConstrainBuilder().set(new RelativeConstrain(yPos), Target.Y); }
|
||||
public static ConstrainBuilder widthR(float width) { return new ConstrainBuilder().set(new RelativeConstrain(width), Target.WIDTH); }
|
||||
public static ConstrainBuilder heightR(float height) { return new ConstrainBuilder().set(new RelativeConstrain(height), Target.HEIGHT); }
|
||||
|
||||
public static ConstrainBuilder parent(Target target) { return new ConstrainBuilder().set(new ParentConstrain(), target); }
|
||||
public static ConstrainBuilder invParent(Target target) { return new ConstrainBuilder().set(new ParentConstrain().invert(), target); }
|
||||
public static ConstrainBuilder parent(float padding, Target target) { return new ConstrainBuilder().set(new ParentConstrain(padding), target); }
|
||||
public static ConstrainBuilder invParent(float padding, Target target) { return new ConstrainBuilder().set(new ParentConstrain(padding).invert(), target); }
|
||||
public static ConstrainBuilder pixel(float pixels, Target target) { return new ConstrainBuilder().set(new PixelConstrain(pixels), target); }
|
||||
public static ConstrainBuilder invPixel(float pixels, Target target) { return new ConstrainBuilder().set(new PixelConstrain(pixels).setInverted(), target); }
|
||||
public static ConstrainBuilder center(Target target) { return new ConstrainBuilder().set(new CenterConstrain(), target); }
|
||||
public static ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return new ConstrainBuilder().set(new DynamicConstrain(provider), target); }
|
||||
|
||||
public static class ConstrainBuilder
|
||||
{
|
||||
Constrain[] constrains = new Constrain[4];
|
||||
|
||||
public ConstrainBuilder set(Constrain value, Target target) {
|
||||
constrains[target.ordinal()] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConstrainBuilder xPos(Constrain xPos) { return set(xPos, Target.X); }
|
||||
public ConstrainBuilder yPos(Constrain yPos) { return set(yPos, Target.Y); }
|
||||
public ConstrainBuilder width(Constrain width) { return set(width, Target.WIDTH); }
|
||||
public ConstrainBuilder height(Constrain height) { return set(height, Target.HEIGHT); }
|
||||
|
||||
public ConstrainBuilder xPos(float xPos) { return set(new PixelConstrain(xPos), Target.X); }
|
||||
public ConstrainBuilder yPos(float yPos) { return set(new PixelConstrain(yPos), Target.Y); }
|
||||
public ConstrainBuilder width(float width) { return set(new PixelConstrain(width), Target.WIDTH); }
|
||||
public ConstrainBuilder height(float height) { return set(new PixelConstrain(height), Target.HEIGHT); }
|
||||
|
||||
public ConstrainBuilder xPosR(float xPos) { return set(new RelativeConstrain(xPos), Target.X); }
|
||||
public ConstrainBuilder yPosR(float yPos) { return set(new RelativeConstrain(yPos), Target.Y); }
|
||||
public ConstrainBuilder widthR(float width) { return set(new RelativeConstrain(width), Target.WIDTH); }
|
||||
public ConstrainBuilder heightR(float height) { return set(new RelativeConstrain(height), Target.HEIGHT); }
|
||||
|
||||
public ConstrainBuilder parent(Target target) { return set(new ParentConstrain(), target); }
|
||||
public ConstrainBuilder invParent(Target target) { return set(new ParentConstrain().invert(), target); }
|
||||
public ConstrainBuilder parent(float padding, Target target) { return set(new ParentConstrain(padding), target); }
|
||||
public ConstrainBuilder invParent(float padding, Target target) { return set(new ParentConstrain(padding).invert(), target); }
|
||||
public ConstrainBuilder pixel(float pixels, Target target) { return set(new PixelConstrain(pixels), target); }
|
||||
public ConstrainBuilder invPixel(float pixels, Target target) { return set(new PixelConstrain(pixels).setInverted(), target); }
|
||||
public ConstrainBuilder center(Target target) { return set(new CenterConstrain(), target); }
|
||||
public ConstrainBuilder dynamic(FloatSupplier provider, Target target) { return set(new DynamicConstrain(provider), target); }
|
||||
|
||||
public Constrains build()
|
||||
{
|
||||
return new Constrains(constrains);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,80 +1,80 @@
|
|||
package speiger.src.coreengine.rendering.gui.renderer.buffer;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.models.DrawCall;
|
||||
import speiger.src.coreengine.rendering.tesselation.Tesselator;
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexList;
|
||||
import speiger.src.coreengine.utils.collections.iterators.IndexIterator;
|
||||
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
|
||||
|
||||
public class RenderBuffer implements Consumer<GuiComponent>, Iterable<DrawCall>
|
||||
{
|
||||
List<DrawCall> drawCalls = new ObjectArrayList<DrawCall>();
|
||||
Tesselator tesselator;
|
||||
|
||||
public RenderBuffer(Tesselator tesselator)
|
||||
{
|
||||
this.tesselator = tesselator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent t)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
public <T extends DrawCall> T get(int index, Class<T> clz)
|
||||
{
|
||||
return (T)drawCalls.get(index);
|
||||
}
|
||||
|
||||
public void addDrawCall(DrawCall call)
|
||||
{
|
||||
drawCalls.add(call);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
drawCalls.clear();
|
||||
}
|
||||
|
||||
public Tesselator start(int shape, VertexList format)
|
||||
{
|
||||
return tesselator.begin(shape, format);
|
||||
}
|
||||
|
||||
public void finishShape(int texture, Tesselator tesselator)
|
||||
{
|
||||
if(!tesselator.isDrawing())
|
||||
{
|
||||
throw new IllegalStateException("Tesselator wasnt filled");
|
||||
}
|
||||
tesselator.finishData();
|
||||
if(tesselator.getVertexCount() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
drawCalls.add(tesselator.getDrawCall(texture));
|
||||
}
|
||||
|
||||
public void finishShape(int texture)
|
||||
{
|
||||
finishShape(texture, tesselator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<DrawCall> iterator()
|
||||
{
|
||||
return drawCalls.iterator();
|
||||
}
|
||||
|
||||
public Iterable<DrawCall> selectionIterator(int...indexes)
|
||||
{
|
||||
return IterableWrapper.wrap(new IndexIterator<>(drawCalls, indexes));
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.renderer.buffer;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
||||
import speiger.src.coreengine.rendering.models.DrawCall;
|
||||
import speiger.src.coreengine.rendering.tesselation.Tesselator;
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexList;
|
||||
import speiger.src.coreengine.utils.collections.iterators.IndexIterator;
|
||||
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
|
||||
|
||||
public class RenderBuffer implements Consumer<GuiComponent>, Iterable<DrawCall>
|
||||
{
|
||||
List<DrawCall> drawCalls = new ObjectArrayList<>();
|
||||
Tesselator tesselator;
|
||||
|
||||
public RenderBuffer(Tesselator tesselator)
|
||||
{
|
||||
this.tesselator = tesselator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GuiComponent t)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
public <T extends DrawCall> T get(int index, Class<T> clz)
|
||||
{
|
||||
return (T)drawCalls.get(index);
|
||||
}
|
||||
|
||||
public void addDrawCall(DrawCall call)
|
||||
{
|
||||
drawCalls.add(call);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
drawCalls.clear();
|
||||
}
|
||||
|
||||
public Tesselator start(int shape, VertexList format)
|
||||
{
|
||||
return tesselator.begin(shape, format);
|
||||
}
|
||||
|
||||
public void finishShape(int texture, Tesselator tesselator)
|
||||
{
|
||||
if(!tesselator.isDrawing())
|
||||
{
|
||||
throw new IllegalStateException("Tesselator wasnt filled");
|
||||
}
|
||||
tesselator.finishData();
|
||||
if(tesselator.getVertexCount() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
drawCalls.add(tesselator.getDrawCall(texture));
|
||||
}
|
||||
|
||||
public void finishShape(int texture)
|
||||
{
|
||||
finishShape(texture, tesselator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<DrawCall> iterator()
|
||||
{
|
||||
return drawCalls.iterator();
|
||||
}
|
||||
|
||||
public Iterable<DrawCall> selectionIterator(int...indexes)
|
||||
{
|
||||
return IterableWrapper.wrap(new IndexIterator<>(drawCalls, indexes));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,142 +1,142 @@
|
|||
package speiger.src.coreengine.rendering.gui.renderer.lexer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import speiger.src.collections.objects.collections.ObjectIterator;
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.collections.objects.utils.ObjectIterators;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.IFontRenderer.CharInstance;
|
||||
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
|
||||
|
||||
public class Line
|
||||
{
|
||||
float totalWidth;
|
||||
float width;
|
||||
int totalLetters = 0;
|
||||
String result = null;
|
||||
List<Word> words = new ObjectArrayList<Word>();
|
||||
|
||||
public Line(float totalWidth)
|
||||
{
|
||||
this.totalWidth = totalWidth;
|
||||
}
|
||||
|
||||
public boolean attemptAddingWord(Word word)
|
||||
{
|
||||
if(word.getWidth() + width > totalWidth)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
width += word.getWidth();
|
||||
words.add(word);
|
||||
totalLetters += word.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addWord(Word word)
|
||||
{
|
||||
width += word.getWidth();
|
||||
words.add(word);
|
||||
totalLetters += word.size();
|
||||
}
|
||||
|
||||
protected void finishLine()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for(Word word : words)
|
||||
{
|
||||
builder.append(word.getLetters());
|
||||
}
|
||||
result = builder.toString();
|
||||
}
|
||||
|
||||
public int getIndex(float width, boolean total)
|
||||
{
|
||||
if(width <= 0F) return (total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0;
|
||||
if(width >= this.width) return ((total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0) + totalLetters;
|
||||
int letters = (total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0;
|
||||
for(int i = 0,m=words.size();i<m;i++)
|
||||
{
|
||||
Word word = words.get(i);
|
||||
if(word.getWidth() > width)
|
||||
{
|
||||
return letters + word.getIndex(width);
|
||||
}
|
||||
width -= word.getWidth();
|
||||
letters += word.size();
|
||||
}
|
||||
return letters;
|
||||
}
|
||||
|
||||
public String getText()
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return words.isEmpty();
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return totalLetters;
|
||||
}
|
||||
|
||||
public int getStart()
|
||||
{
|
||||
return words.isEmpty() ? 0 : words.get(0).getStartIndex();
|
||||
}
|
||||
|
||||
public int getEnd()
|
||||
{
|
||||
return words.isEmpty() ? 0 : words.get(words.size() - 1).getEndIndex();
|
||||
}
|
||||
|
||||
public Word getWord(int letterIndex)
|
||||
{
|
||||
for(int i = 0;i<words.size();i++)
|
||||
{
|
||||
Word word = words.get(i);
|
||||
if(word.size() >= letterIndex)
|
||||
{
|
||||
return word;
|
||||
}
|
||||
letterIndex -= word.size();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public float getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
public float getWidth(int index)
|
||||
{
|
||||
if(index <= 0) return 0F;
|
||||
else if(index >= totalLetters) return width;
|
||||
float width = 0F;
|
||||
for(int i = 0,m=words.size();i<m;i++)
|
||||
{
|
||||
Word word = words.get(i);
|
||||
if(word.size() > index)
|
||||
{
|
||||
return width + word.getWidth(index);
|
||||
}
|
||||
width += word.getWidth();
|
||||
index -= word.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Iterable<CharInstance> letterIterator()
|
||||
{
|
||||
ObjectIterator<CharInstance>[] arrays = new ObjectIterator[words.size()];
|
||||
for(int i = 0,m=words.size();i<m;i++)
|
||||
{
|
||||
arrays[i] = words.get(i).objectInstanceIterator();
|
||||
}
|
||||
return IterableWrapper.wrap(ObjectIterators.concat(arrays));
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.renderer.lexer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import speiger.src.collections.objects.collections.ObjectIterator;
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.collections.objects.utils.ObjectIterators;
|
||||
import speiger.src.coreengine.rendering.gui.renderer.IFontRenderer.CharInstance;
|
||||
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
|
||||
|
||||
public class Line
|
||||
{
|
||||
float totalWidth;
|
||||
float width;
|
||||
int totalLetters = 0;
|
||||
String result = null;
|
||||
List<Word> words = new ObjectArrayList<>();
|
||||
|
||||
public Line(float totalWidth)
|
||||
{
|
||||
this.totalWidth = totalWidth;
|
||||
}
|
||||
|
||||
public boolean attemptAddingWord(Word word)
|
||||
{
|
||||
if(word.getWidth() + width > totalWidth)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
width += word.getWidth();
|
||||
words.add(word);
|
||||
totalLetters += word.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addWord(Word word)
|
||||
{
|
||||
width += word.getWidth();
|
||||
words.add(word);
|
||||
totalLetters += word.size();
|
||||
}
|
||||
|
||||
protected void finishLine()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for(Word word : words)
|
||||
{
|
||||
builder.append(word.getLetters());
|
||||
}
|
||||
result = builder.toString();
|
||||
}
|
||||
|
||||
public int getIndex(float width, boolean total)
|
||||
{
|
||||
if(width <= 0F) return (total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0;
|
||||
if(width >= this.width) return ((total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0) + totalLetters;
|
||||
int letters = (total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0;
|
||||
for(int i = 0,m=words.size();i<m;i++)
|
||||
{
|
||||
Word word = words.get(i);
|
||||
if(word.getWidth() > width)
|
||||
{
|
||||
return letters + word.getIndex(width);
|
||||
}
|
||||
width -= word.getWidth();
|
||||
letters += word.size();
|
||||
}
|
||||
return letters;
|
||||
}
|
||||
|
||||
public String getText()
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return words.isEmpty();
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return totalLetters;
|
||||
}
|
||||
|
||||
public int getStart()
|
||||
{
|
||||
return words.isEmpty() ? 0 : words.get(0).getStartIndex();
|
||||
}
|
||||
|
||||
public int getEnd()
|
||||
{
|
||||
return words.isEmpty() ? 0 : words.get(words.size() - 1).getEndIndex();
|
||||
}
|
||||
|
||||
public Word getWord(int letterIndex)
|
||||
{
|
||||
for(int i = 0;i<words.size();i++)
|
||||
{
|
||||
Word word = words.get(i);
|
||||
if(word.size() >= letterIndex)
|
||||
{
|
||||
return word;
|
||||
}
|
||||
letterIndex -= word.size();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public float getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
public float getWidth(int index)
|
||||
{
|
||||
if(index <= 0) return 0F;
|
||||
else if(index >= totalLetters) return width;
|
||||
float width = 0F;
|
||||
for(int i = 0,m=words.size();i<m;i++)
|
||||
{
|
||||
Word word = words.get(i);
|
||||
if(word.size() > index)
|
||||
{
|
||||
return width + word.getWidth(index);
|
||||
}
|
||||
width += word.getWidth();
|
||||
index -= word.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Iterable<CharInstance> letterIterator()
|
||||
{
|
||||
ObjectIterator<CharInstance>[] arrays = new ObjectIterator[words.size()];
|
||||
for(int i = 0,m=words.size();i<m;i++)
|
||||
{
|
||||
arrays[i] = words.get(i).objectInstanceIterator();
|
||||
}
|
||||
return IterableWrapper.wrap(ObjectIterators.concat(arrays));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,158 +1,158 @@
|
|||
package speiger.src.coreengine.rendering.gui.renderer.lexer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.math.vector.ints.Vec2i;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
|
||||
public class TextMetadata
|
||||
{
|
||||
TextComponent owner;
|
||||
List<Line> lines = new ObjectArrayList<Line>();
|
||||
float startX;
|
||||
float startY;
|
||||
float maxHeight;
|
||||
float maxWidth = 0F;
|
||||
float scale;
|
||||
|
||||
public TextMetadata(TextComponent owner)
|
||||
{
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
scale = owner.getTextScale();
|
||||
lines.clear();
|
||||
maxWidth = 0F;
|
||||
maxHeight = 0F;
|
||||
startX = 0F;
|
||||
startY = 0F;
|
||||
}
|
||||
|
||||
public void addLine(Line line)
|
||||
{
|
||||
lines.add(line);
|
||||
maxWidth = Math.max(maxWidth, line.getWidth());
|
||||
maxHeight = lines.size() * owner.getFont().height() * scale;
|
||||
}
|
||||
|
||||
public void setStart(float x, float y)
|
||||
{
|
||||
startX = x;
|
||||
startY = y;
|
||||
}
|
||||
|
||||
public float getStartX()
|
||||
{
|
||||
return startX;
|
||||
}
|
||||
|
||||
public float getStartY()
|
||||
{
|
||||
return startY;
|
||||
}
|
||||
|
||||
public float getMaxHeight()
|
||||
{
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
public float getMaxWidth()
|
||||
{
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
public float getWidth(int letterIndex)
|
||||
{
|
||||
return lines.isEmpty() ? 0F : lines.get(0).getWidth(letterIndex);
|
||||
}
|
||||
|
||||
public float getWidth(int posX, int posY)
|
||||
{
|
||||
return lines.size() > posY ? lines.get(posY).getWidth(posX) : 0F;
|
||||
}
|
||||
|
||||
public float getLineWidth(int line)
|
||||
{
|
||||
return lines.size() > line ? lines.get(line).getWidth() : 0F;
|
||||
}
|
||||
|
||||
public Word getWord(int letterIndex)
|
||||
{
|
||||
return lines.isEmpty() ? null : lines.get(0).getWord(letterIndex);
|
||||
}
|
||||
|
||||
public Line getLine(int line)
|
||||
{
|
||||
return lines.size() > line ? lines.get(line) : null;
|
||||
}
|
||||
|
||||
public int moveUp(Vec2i pos)
|
||||
{
|
||||
if(pos.getY() + 1 < lines.size())
|
||||
{
|
||||
float width = lines.get(pos.getY()).getWidth(pos.getX());
|
||||
return lines.get(pos.getY() + 1).getIndex(width, true);
|
||||
}
|
||||
return lines.isEmpty() ? 0 : lines.get(lines.size() - 1).getEnd();
|
||||
}
|
||||
|
||||
public int moveDown(Vec2i pos)
|
||||
{
|
||||
if(pos.getY() > 0 && pos.getY() - 1 < lines.size())
|
||||
{
|
||||
float width = lines.get(pos.getY()).getWidth(pos.getX());
|
||||
return lines.get(pos.getY() - 1).getIndex(width, true);
|
||||
}
|
||||
return lines.isEmpty() ? 0 : lines.get(0).getStart();
|
||||
}
|
||||
|
||||
public int getIndex(float width)
|
||||
{
|
||||
return lines.size() > 0 ? lines.get(0).getIndex(width, false) : 0;
|
||||
}
|
||||
|
||||
public int getIndex(float width, float height)
|
||||
{
|
||||
return lines.isEmpty() ? 0 : lines.get(MathUtils.clamp(0, lines.size() - 1, (int)(height / (owner.getFont().height() * scale)))).getIndex(width, true);
|
||||
}
|
||||
|
||||
public void getIndex(float width, float height, Vec2i result)
|
||||
{
|
||||
if(lines.isEmpty())
|
||||
{
|
||||
result.negate();
|
||||
return;
|
||||
}
|
||||
int index = MathUtils.clamp(0, lines.size() - 1, (int)(height / (owner.getFont().height() * scale)));
|
||||
result.set(lines.get(index).getIndex(width, false), index);
|
||||
}
|
||||
|
||||
public void convert(int index, Vec2i result)
|
||||
{
|
||||
result.set(Vec2i.ZERO);
|
||||
for(int i = 0,m=lines.size();i<m;i++)
|
||||
{
|
||||
Line line = lines.get(i);
|
||||
if(line.size() >= index)
|
||||
{
|
||||
result.add(index, i);
|
||||
return;
|
||||
}
|
||||
index -= line.size();
|
||||
}
|
||||
}
|
||||
|
||||
public int convert(Vec2i input)
|
||||
{
|
||||
int index = input.getX();
|
||||
for(int i = 0,m=input.getY();i<m;i++)
|
||||
{
|
||||
index += lines.get(i).size();
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.gui.renderer.lexer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.math.MathUtils;
|
||||
import speiger.src.coreengine.math.vector.ints.Vec2i;
|
||||
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
||||
|
||||
public class TextMetadata
|
||||
{
|
||||
TextComponent owner;
|
||||
List<Line> lines = new ObjectArrayList<>();
|
||||
float startX;
|
||||
float startY;
|
||||
float maxHeight;
|
||||
float maxWidth = 0F;
|
||||
float scale;
|
||||
|
||||
public TextMetadata(TextComponent owner)
|
||||
{
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
scale = owner.getTextScale();
|
||||
lines.clear();
|
||||
maxWidth = 0F;
|
||||
maxHeight = 0F;
|
||||
startX = 0F;
|
||||
startY = 0F;
|
||||
}
|
||||
|
||||
public void addLine(Line line)
|
||||
{
|
||||
lines.add(line);
|
||||
maxWidth = Math.max(maxWidth, line.getWidth());
|
||||
maxHeight = lines.size() * owner.getFont().height() * scale;
|
||||
}
|
||||
|
||||
public void setStart(float x, float y)
|
||||
{
|
||||
startX = x;
|
||||
startY = y;
|
||||
}
|
||||
|
||||
public float getStartX()
|
||||
{
|
||||
return startX;
|
||||
}
|
||||
|
||||
public float getStartY()
|
||||
{
|
||||
return startY;
|
||||
}
|
||||
|
||||
public float getMaxHeight()
|
||||
{
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
public float getMaxWidth()
|
||||
{
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
public float getWidth(int letterIndex)
|
||||
{
|
||||
return lines.isEmpty() ? 0F : lines.get(0).getWidth(letterIndex);
|
||||
}
|
||||
|
||||
public float getWidth(int posX, int posY)
|
||||
{
|
||||
return lines.size() > posY ? lines.get(posY).getWidth(posX) : 0F;
|
||||
}
|
||||
|
||||
public float getLineWidth(int line)
|
||||
{
|
||||
return lines.size() > line ? lines.get(line).getWidth() : 0F;
|
||||
}
|
||||
|
||||
public Word getWord(int letterIndex)
|
||||
{
|
||||
return lines.isEmpty() ? null : lines.get(0).getWord(letterIndex);
|
||||
}
|
||||
|
||||
public Line getLine(int line)
|
||||
{
|
||||
return lines.size() > line ? lines.get(line) : null;
|
||||
}
|
||||
|
||||
public int moveUp(Vec2i pos)
|
||||
{
|
||||
if(pos.getY() + 1 < lines.size())
|
||||
{
|
||||
float width = lines.get(pos.getY()).getWidth(pos.getX());
|
||||
return lines.get(pos.getY() + 1).getIndex(width, true);
|
||||
}
|
||||
return lines.isEmpty() ? 0 : lines.get(lines.size() - 1).getEnd();
|
||||
}
|
||||
|
||||
public int moveDown(Vec2i pos)
|
||||
{
|
||||
if(pos.getY() > 0 && pos.getY() - 1 < lines.size())
|
||||
{
|
||||
float width = lines.get(pos.getY()).getWidth(pos.getX());
|
||||
return lines.get(pos.getY() - 1).getIndex(width, true);
|
||||
}
|
||||
return lines.isEmpty() ? 0 : lines.get(0).getStart();
|
||||
}
|
||||
|
||||
public int getIndex(float width)
|
||||
{
|
||||
return lines.size() > 0 ? lines.get(0).getIndex(width, false) : 0;
|
||||
}
|
||||
|
||||
public int getIndex(float width, float height)
|
||||
{
|
||||
return lines.isEmpty() ? 0 : lines.get(MathUtils.clamp(0, lines.size() - 1, (int)(height / (owner.getFont().height() * scale)))).getIndex(width, true);
|
||||
}
|
||||
|
||||
public void getIndex(float width, float height, Vec2i result)
|
||||
{
|
||||
if(lines.isEmpty())
|
||||
{
|
||||
result.negate();
|
||||
return;
|
||||
}
|
||||
int index = MathUtils.clamp(0, lines.size() - 1, (int)(height / (owner.getFont().height() * scale)));
|
||||
result.set(lines.get(index).getIndex(width, false), index);
|
||||
}
|
||||
|
||||
public void convert(int index, Vec2i result)
|
||||
{
|
||||
result.set(Vec2i.ZERO);
|
||||
for(int i = 0,m=lines.size();i<m;i++)
|
||||
{
|
||||
Line line = lines.get(i);
|
||||
if(line.size() >= index)
|
||||
{
|
||||
result.add(index, i);
|
||||
return;
|
||||
}
|
||||
index -= line.size();
|
||||
}
|
||||
}
|
||||
|
||||
public int convert(Vec2i input)
|
||||
{
|
||||
int index = input.getX();
|
||||
for(int i = 0,m=input.getY();i<m;i++)
|
||||
{
|
||||
index += lines.get(i).size();
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,23 +1,23 @@
|
|||
package speiger.src.coreengine.rendering.shader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ShaderEntry<T> implements Consumer<T>
|
||||
{
|
||||
List<T> shaders;
|
||||
int index;
|
||||
|
||||
public ShaderEntry(List<T> shaders, int index)
|
||||
{
|
||||
this.shaders = shaders;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(T t)
|
||||
{
|
||||
shaders.set(index, t);
|
||||
}
|
||||
|
||||
}
|
||||
package speiger.src.coreengine.rendering.shader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ShaderEntry<T> implements Consumer<T>
|
||||
{
|
||||
List<T> shaders;
|
||||
int index;
|
||||
|
||||
public ShaderEntry(List<T> shaders, int index)
|
||||
{
|
||||
this.shaders = shaders;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(T t)
|
||||
{
|
||||
shaders.set(index, t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,276 +1,276 @@
|
|||
package speiger.src.coreengine.rendering.tesselation;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import speiger.src.coreengine.math.vector.floats.Vec2f;
|
||||
import speiger.src.coreengine.math.vector.floats.Vec3f;
|
||||
import speiger.src.coreengine.rendering.models.DrawCall;
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
|
||||
|
||||
public class Tesselator implements IVertexBuilder
|
||||
{
|
||||
boolean drawing = false;
|
||||
int drawType = 0;
|
||||
|
||||
VertexList currentList;
|
||||
VertexElement currentElement;
|
||||
int currentIndex = 0;
|
||||
|
||||
Vec3f offset = Vec3f.mutable();
|
||||
Vec2f effects = Vec2f.mutable(1F);
|
||||
|
||||
FloatBuffer buffer;
|
||||
int vertexes = 0;
|
||||
|
||||
public Tesselator(int capacity)
|
||||
{
|
||||
buffer = FloatBuffer.allocate(capacity);
|
||||
}
|
||||
|
||||
public Tesselator(FloatBuffer buffer)
|
||||
{
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
public Tesselator begin(int glType, VertexList list)
|
||||
{
|
||||
if(drawing)
|
||||
{
|
||||
throw new RuntimeException("Already Drawing");
|
||||
}
|
||||
drawType = glType;
|
||||
drawing = true;
|
||||
currentList = list;
|
||||
currentElement = list.getElement(0);
|
||||
currentIndex = 0;
|
||||
buffer.clear();
|
||||
vertexes = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator changeGLType(int glType)
|
||||
{
|
||||
if(!drawing)
|
||||
{
|
||||
throw new RuntimeException("Can not change type");
|
||||
}
|
||||
drawType = glType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator resetVertexes()
|
||||
{
|
||||
vertexes = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator setBrightness(float value)
|
||||
{
|
||||
effects.setX(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator setVisibilty(float value)
|
||||
{
|
||||
effects.setY(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public float getBrightness()
|
||||
{
|
||||
return effects.getX();
|
||||
}
|
||||
|
||||
public float getVisibility()
|
||||
{
|
||||
return effects.getY();
|
||||
}
|
||||
|
||||
public Tesselator resetEffects()
|
||||
{
|
||||
effects.set(Vec2f.ONE);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator offset(float x, float y, float z)
|
||||
{
|
||||
offset.add(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator setOffset(float x, float y, float z)
|
||||
{
|
||||
offset.set(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator pos(float x, float y)
|
||||
{
|
||||
validateElement(ElementUsage.POS, 2);
|
||||
buffer.put(x + offset.getX());
|
||||
buffer.put(y + offset.getY());
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator pos(float x, float y, float z)
|
||||
{
|
||||
validateElement(ElementUsage.POS, 3);
|
||||
buffer.put(x + offset.getX());
|
||||
buffer.put(y + offset.getY());
|
||||
buffer.put(z + offset.getZ());
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator color3f(float r, float g, float b)
|
||||
{
|
||||
validateElement(ElementUsage.COLOR, 3);
|
||||
buffer.put(r * effects.getX());
|
||||
buffer.put(g * effects.getX());
|
||||
buffer.put(b * effects.getX());
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator color4f(float r, float g, float b, float a)
|
||||
{
|
||||
validateElement(ElementUsage.COLOR, 4);
|
||||
buffer.put(r * effects.getX());
|
||||
buffer.put(g * effects.getX());
|
||||
buffer.put(b * effects.getX());
|
||||
buffer.put(a * effects.getY());
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator tex(float u, float v)
|
||||
{
|
||||
validateElement(ElementUsage.UV, 2);
|
||||
buffer.put(u);
|
||||
buffer.put(v);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator normal(float x, float y, float z)
|
||||
{
|
||||
validateElement(ElementUsage.NORMAL, 3);
|
||||
buffer.put(x);
|
||||
buffer.put(y);
|
||||
buffer.put(z);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator custom(float x)
|
||||
{
|
||||
validateElement(ElementUsage.CUSTOM, 1);
|
||||
buffer.put(x);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator custom(float x, float y)
|
||||
{
|
||||
validateElement(ElementUsage.CUSTOM, 2);
|
||||
buffer.put(x);
|
||||
buffer.put(y);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator custom(float x, float y, float z)
|
||||
{
|
||||
validateElement(ElementUsage.CUSTOM, 3);
|
||||
buffer.put(x);
|
||||
buffer.put(y);
|
||||
buffer.put(z);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator custom(float x, float y, float z, float w)
|
||||
{
|
||||
validateElement(ElementUsage.CUSTOM, 4);
|
||||
buffer.put(x);
|
||||
buffer.put(y);
|
||||
buffer.put(z);
|
||||
buffer.put(w);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator endVertex()
|
||||
{
|
||||
vertexes++;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator finishData()
|
||||
{
|
||||
drawing = false;
|
||||
buffer.flip();
|
||||
return this;
|
||||
}
|
||||
|
||||
public float[] getData()
|
||||
{
|
||||
float[] data = new float[currentList.getOffsets() * vertexes];
|
||||
buffer.get(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public DrawCall getDrawCall(int texture)
|
||||
{
|
||||
float[] data = new float[currentList.getOffsets() * vertexes];
|
||||
buffer.get(data);
|
||||
return new DrawCall(drawType, texture, data, vertexes);
|
||||
}
|
||||
|
||||
public boolean isDrawing()
|
||||
{
|
||||
return drawing;
|
||||
}
|
||||
|
||||
public boolean hasTexture()
|
||||
{
|
||||
return currentList.hasType(ElementUsage.UV);
|
||||
}
|
||||
|
||||
public int getGLDrawType()
|
||||
{
|
||||
return drawType;
|
||||
}
|
||||
|
||||
public void validateElement(ElementUsage usage, int componentSize)
|
||||
{
|
||||
if(currentElement.getUsage() == usage && currentElement.getSize() == componentSize && drawing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Invalid Argument, Drawing: "+drawing+", Element: "+usage+", Expected: "+currentElement.getUsage()+", Size: "+componentSize+", Expected Size: "+currentElement.getSize());
|
||||
}
|
||||
|
||||
protected void nextElement()
|
||||
{
|
||||
currentIndex = (currentIndex + 1) % currentList.getElementCount();
|
||||
currentElement = currentList.getElement(currentIndex);
|
||||
}
|
||||
|
||||
public int getVertexCount()
|
||||
{
|
||||
return vertexes;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.tesselation;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import speiger.src.coreengine.math.vector.floats.Vec2f;
|
||||
import speiger.src.coreengine.math.vector.floats.Vec3f;
|
||||
import speiger.src.coreengine.rendering.models.DrawCall;
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
|
||||
|
||||
public class Tesselator implements IVertexBuilder
|
||||
{
|
||||
boolean drawing = false;
|
||||
int drawType = 0;
|
||||
|
||||
VertexList currentList;
|
||||
VertexElement currentElement;
|
||||
int currentIndex = 0;
|
||||
|
||||
Vec3f offset = Vec3f.mutable();
|
||||
Vec2f effects = Vec2f.mutable(1F);
|
||||
|
||||
FloatBuffer buffer;
|
||||
int vertexes = 0;
|
||||
|
||||
public Tesselator(int capacity)
|
||||
{
|
||||
buffer = FloatBuffer.allocate(capacity);
|
||||
}
|
||||
|
||||
public Tesselator(FloatBuffer buffer)
|
||||
{
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
public Tesselator begin(int glType, VertexList list)
|
||||
{
|
||||
if(drawing)
|
||||
{
|
||||
throw new RuntimeException("Already Drawing");
|
||||
}
|
||||
drawType = glType;
|
||||
drawing = true;
|
||||
currentList = list;
|
||||
currentElement = list.get(0);
|
||||
currentIndex = 0;
|
||||
buffer.clear();
|
||||
vertexes = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator changeGLType(int glType)
|
||||
{
|
||||
if(!drawing)
|
||||
{
|
||||
throw new RuntimeException("Can not change type");
|
||||
}
|
||||
drawType = glType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator resetVertexes()
|
||||
{
|
||||
vertexes = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator setBrightness(float value)
|
||||
{
|
||||
effects.setX(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator setVisibilty(float value)
|
||||
{
|
||||
effects.setY(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public float getBrightness()
|
||||
{
|
||||
return effects.getX();
|
||||
}
|
||||
|
||||
public float getVisibility()
|
||||
{
|
||||
return effects.getY();
|
||||
}
|
||||
|
||||
public Tesselator resetEffects()
|
||||
{
|
||||
effects.set(Vec2f.ONE);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator offset(float x, float y, float z)
|
||||
{
|
||||
offset.add(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator setOffset(float x, float y, float z)
|
||||
{
|
||||
offset.set(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator pos(float x, float y)
|
||||
{
|
||||
validateElement(ElementUsage.POS, 2);
|
||||
buffer.put(x + offset.getX());
|
||||
buffer.put(y + offset.getY());
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator pos(float x, float y, float z)
|
||||
{
|
||||
validateElement(ElementUsage.POS, 3);
|
||||
buffer.put(x + offset.getX());
|
||||
buffer.put(y + offset.getY());
|
||||
buffer.put(z + offset.getZ());
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator color3f(float r, float g, float b)
|
||||
{
|
||||
validateElement(ElementUsage.COLOR, 3);
|
||||
buffer.put(r * effects.getX());
|
||||
buffer.put(g * effects.getX());
|
||||
buffer.put(b * effects.getX());
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator color4f(float r, float g, float b, float a)
|
||||
{
|
||||
validateElement(ElementUsage.COLOR, 4);
|
||||
buffer.put(r * effects.getX());
|
||||
buffer.put(g * effects.getX());
|
||||
buffer.put(b * effects.getX());
|
||||
buffer.put(a * effects.getY());
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator tex(float u, float v)
|
||||
{
|
||||
validateElement(ElementUsage.UV, 2);
|
||||
buffer.put(u);
|
||||
buffer.put(v);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator normal(float x, float y, float z)
|
||||
{
|
||||
validateElement(ElementUsage.NORMAL, 3);
|
||||
buffer.put(x);
|
||||
buffer.put(y);
|
||||
buffer.put(z);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator custom(float x)
|
||||
{
|
||||
validateElement(ElementUsage.CUSTOM, 1);
|
||||
buffer.put(x);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator custom(float x, float y)
|
||||
{
|
||||
validateElement(ElementUsage.CUSTOM, 2);
|
||||
buffer.put(x);
|
||||
buffer.put(y);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator custom(float x, float y, float z)
|
||||
{
|
||||
validateElement(ElementUsage.CUSTOM, 3);
|
||||
buffer.put(x);
|
||||
buffer.put(y);
|
||||
buffer.put(z);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator custom(float x, float y, float z, float w)
|
||||
{
|
||||
validateElement(ElementUsage.CUSTOM, 4);
|
||||
buffer.put(x);
|
||||
buffer.put(y);
|
||||
buffer.put(z);
|
||||
buffer.put(w);
|
||||
nextElement();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tesselator endVertex()
|
||||
{
|
||||
vertexes++;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tesselator finishData()
|
||||
{
|
||||
drawing = false;
|
||||
buffer.flip();
|
||||
return this;
|
||||
}
|
||||
|
||||
public float[] getData()
|
||||
{
|
||||
float[] data = new float[currentList.getOffsets() * vertexes];
|
||||
buffer.get(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public DrawCall getDrawCall(int texture)
|
||||
{
|
||||
float[] data = new float[currentList.getOffsets() * vertexes];
|
||||
buffer.get(data);
|
||||
return new DrawCall(drawType, texture, data, vertexes);
|
||||
}
|
||||
|
||||
public boolean isDrawing()
|
||||
{
|
||||
return drawing;
|
||||
}
|
||||
|
||||
public boolean hasTexture()
|
||||
{
|
||||
return currentList.hasType(ElementUsage.UV);
|
||||
}
|
||||
|
||||
public int getGLDrawType()
|
||||
{
|
||||
return drawType;
|
||||
}
|
||||
|
||||
public void validateElement(ElementUsage usage, int componentSize)
|
||||
{
|
||||
if(currentElement.getUsage() == usage && currentElement.getSize() == componentSize && drawing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Invalid Argument, Drawing: "+drawing+", Element: "+usage+", Expected: "+currentElement.getUsage()+", Size: "+componentSize+", Expected Size: "+currentElement.getSize());
|
||||
}
|
||||
|
||||
protected void nextElement()
|
||||
{
|
||||
currentIndex = (currentIndex + 1) % currentList.size();
|
||||
currentElement = currentList.get(currentIndex);
|
||||
}
|
||||
|
||||
public int getVertexCount()
|
||||
{
|
||||
return vertexes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,71 +1,69 @@
|
|||
package speiger.src.coreengine.rendering.tesselation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import speiger.src.collections.ints.lists.IntArrayList;
|
||||
import speiger.src.collections.ints.lists.IntList;
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
|
||||
import speiger.src.coreengine.utils.collections.iterators.ReadOnlyIterator;
|
||||
|
||||
public class VertexList implements Iterable<VertexElement>
|
||||
{
|
||||
List<VertexElement> elements = new ArrayList<VertexElement>();
|
||||
Set<ElementUsage> types = EnumSet.noneOf(ElementUsage.class);
|
||||
IntList offsets = new IntArrayList();
|
||||
int totalOffset;
|
||||
|
||||
public VertexList()
|
||||
{
|
||||
}
|
||||
|
||||
public VertexList(VertexList vertexList)
|
||||
{
|
||||
elements.addAll(vertexList.elements);
|
||||
offsets.addAll(vertexList.offsets);
|
||||
totalOffset = vertexList.totalOffset;
|
||||
}
|
||||
|
||||
public void addElement(VertexElement element)
|
||||
{
|
||||
elements.add(element);
|
||||
offsets.add(totalOffset);
|
||||
totalOffset += element.getSize();
|
||||
types.add(element.getUsage());
|
||||
}
|
||||
|
||||
public int getOffsets()
|
||||
{
|
||||
return totalOffset;
|
||||
}
|
||||
|
||||
public int getElementCount()
|
||||
{
|
||||
return elements.size();
|
||||
}
|
||||
|
||||
public VertexElement getElement(int index)
|
||||
{
|
||||
return elements.get(index);
|
||||
}
|
||||
|
||||
public int getOffset(int index)
|
||||
{
|
||||
return offsets.getInt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<VertexElement> iterator()
|
||||
{
|
||||
return new ReadOnlyIterator<VertexElement>(elements.iterator());
|
||||
}
|
||||
|
||||
public boolean hasType(ElementUsage type)
|
||||
{
|
||||
return types.contains(type);
|
||||
}
|
||||
|
||||
}
|
||||
package speiger.src.coreengine.rendering.tesselation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import speiger.src.collections.ints.lists.IntArrayList;
|
||||
import speiger.src.collections.ints.lists.IntList;
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
|
||||
import speiger.src.coreengine.utils.collections.iterators.ReadOnlyIterator;
|
||||
|
||||
public class VertexList implements Iterable<VertexElement>
|
||||
{
|
||||
List<VertexElement> elements = new ArrayList<VertexElement>();
|
||||
Set<ElementUsage> types = EnumSet.noneOf(ElementUsage.class);
|
||||
IntList offsets = new IntArrayList();
|
||||
int totalOffset;
|
||||
|
||||
public VertexList() {}
|
||||
|
||||
public VertexList(VertexList vertexList)
|
||||
{
|
||||
elements.addAll(vertexList.elements);
|
||||
offsets.addAll(vertexList.offsets);
|
||||
totalOffset = vertexList.totalOffset;
|
||||
}
|
||||
|
||||
public VertexList add(VertexElement element)
|
||||
{
|
||||
elements.add(element);
|
||||
offsets.add(totalOffset);
|
||||
totalOffset += element.getSize();
|
||||
types.add(element.getUsage());
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getOffsets()
|
||||
{
|
||||
return totalOffset;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return elements.size();
|
||||
}
|
||||
|
||||
public VertexElement get(int index)
|
||||
{
|
||||
return elements.get(index);
|
||||
}
|
||||
|
||||
public int getOffset(int index)
|
||||
{
|
||||
return offsets.getInt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<VertexElement> iterator()
|
||||
{
|
||||
return new ReadOnlyIterator<>(elements.iterator());
|
||||
}
|
||||
|
||||
public boolean hasType(ElementUsage type)
|
||||
{
|
||||
return types.contains(type);
|
||||
}
|
||||
}
|
|
@ -1,47 +1,23 @@
|
|||
package speiger.src.coreengine.rendering.tesselation;
|
||||
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
|
||||
|
||||
public class VertexType
|
||||
{
|
||||
public static final VertexElement POSITION_2F = new VertexElement(2, ElementUsage.POS);
|
||||
public static final VertexElement POSITION_3F = new VertexElement(3, ElementUsage.POS);
|
||||
public static final VertexElement TEXTURE_2F = new VertexElement(2, ElementUsage.UV);
|
||||
public static final VertexElement COLOR_3F = new VertexElement(3, ElementUsage.COLOR);
|
||||
public static final VertexElement COLOR_4F = new VertexElement(4, ElementUsage.COLOR);
|
||||
public static final VertexElement NORMAL_3F = new VertexElement(3, ElementUsage.NORMAL);
|
||||
public static final VertexElement CUSTOM_4F = new VertexElement(4, ElementUsage.CUSTOM);
|
||||
|
||||
public static final VertexList POS_COLOR_3F = new VertexList();
|
||||
public static final VertexList POS_COLOR_4F = new VertexList();
|
||||
public static final VertexList POS_COLOR_2F = new VertexList();
|
||||
public static final VertexList POS_TEX = new VertexList();
|
||||
public static final VertexList TERRAIN = new VertexList();
|
||||
|
||||
public static final VertexList UI = new VertexList();
|
||||
public static final VertexList IN_WORLD_UI = new VertexList();
|
||||
|
||||
static
|
||||
{
|
||||
UI.addElement(POSITION_3F);
|
||||
UI.addElement(TEXTURE_2F);
|
||||
UI.addElement(COLOR_4F);
|
||||
|
||||
IN_WORLD_UI.addElement(POSITION_3F);
|
||||
IN_WORLD_UI.addElement(TEXTURE_2F);
|
||||
IN_WORLD_UI.addElement(COLOR_4F);
|
||||
IN_WORLD_UI.addElement(CUSTOM_4F);
|
||||
|
||||
TERRAIN.addElement(POSITION_3F);
|
||||
TERRAIN.addElement(COLOR_3F);
|
||||
TERRAIN.addElement(NORMAL_3F);
|
||||
POS_COLOR_2F.addElement(POSITION_2F);
|
||||
POS_COLOR_2F.addElement(COLOR_4F);
|
||||
POS_COLOR_3F.addElement(POSITION_3F);
|
||||
POS_COLOR_3F.addElement(COLOR_3F);
|
||||
POS_COLOR_4F.addElement(POSITION_3F);
|
||||
POS_COLOR_4F.addElement(COLOR_4F);
|
||||
POS_TEX.addElement(POSITION_3F);
|
||||
POS_TEX.addElement(TEXTURE_2F);
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.tesselation;
|
||||
|
||||
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
|
||||
|
||||
public class VertexType
|
||||
{
|
||||
public static final VertexElement POSITION_2F = new VertexElement(2, ElementUsage.POS);
|
||||
public static final VertexElement POSITION_3F = new VertexElement(3, ElementUsage.POS);
|
||||
public static final VertexElement TEXTURE_2F = new VertexElement(2, ElementUsage.UV);
|
||||
public static final VertexElement COLOR_3F = new VertexElement(3, ElementUsage.COLOR);
|
||||
public static final VertexElement COLOR_4F = new VertexElement(4, ElementUsage.COLOR);
|
||||
public static final VertexElement NORMAL_3F = new VertexElement(3, ElementUsage.NORMAL);
|
||||
public static final VertexElement CUSTOM_4F = new VertexElement(4, ElementUsage.CUSTOM);
|
||||
|
||||
public static final VertexList POS_COLOR_2F = new VertexList().add(POSITION_2F).add(COLOR_4F);
|
||||
public static final VertexList POS_COLOR_3F = new VertexList().add(POSITION_3F).add(COLOR_3F);
|
||||
public static final VertexList POS_COLOR_4F = new VertexList().add(POSITION_3F).add(COLOR_4F);
|
||||
public static final VertexList POS_TEX = new VertexList().add(POSITION_3F).add(TEXTURE_2F);
|
||||
public static final VertexList TERRAIN = new VertexList().add(POSITION_3F).add(COLOR_3F).add(NORMAL_3F);
|
||||
|
||||
public static final VertexList UI = new VertexList().add(POSITION_3F).add(TEXTURE_2F).add(COLOR_4F);
|
||||
public static final VertexList IN_WORLD_UI = new VertexList().add(POSITION_3F).add(TEXTURE_2F).add(COLOR_4F).add(CUSTOM_4F);
|
||||
}
|
||||
|
|
|
@ -1,131 +1,139 @@
|
|||
package speiger.src.coreengine.rendering.utils;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
import org.lwjgl.opengl.GL31;
|
||||
import org.lwjgl.opengl.GL44;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.rendering.utils.states.BlendState;
|
||||
import speiger.src.coreengine.rendering.utils.states.CullState;
|
||||
import speiger.src.coreengine.rendering.utils.states.GLProvoking;
|
||||
import speiger.src.coreengine.rendering.utils.states.GLState;
|
||||
import speiger.src.coreengine.rendering.utils.states.GLWireFrame;
|
||||
import speiger.src.coreengine.rendering.utils.states.IGLState;
|
||||
import speiger.src.coreengine.rendering.utils.states.LineSize;
|
||||
import speiger.src.coreengine.rendering.utils.states.PointSize;
|
||||
import speiger.src.coreengine.utils.counters.averager.Counter;
|
||||
|
||||
public class GLUtils
|
||||
{
|
||||
static final List<IGLState> ALL_STATES = new ObjectArrayList<>();
|
||||
public static final GLState MULTI_SAMPLING = addState(new GLState(GL13.GL_MULTISAMPLE, false));
|
||||
public static final GLState WIRE_FRAME = addState(new GLWireFrame());
|
||||
public static final GLState PROVOKING_VERTEX = addState(new GLProvoking());
|
||||
public static final GLState DEBTH_TEST = addState(new GLState(GL11.GL_DEPTH_TEST, false));
|
||||
public static final CullState CULL_FACE = addState(new CullState(GL11.GL_BACK));
|
||||
public static final BlendState BLEND = addState(new BlendState());
|
||||
public static final GLState CLIP_PLANE0 = addState(new GLState(GL11.GL_CLIP_PLANE0, false));
|
||||
public static final PointSize POINT_SIZE = addState(new PointSize());
|
||||
public static final LineSize LINE_SIZE = addState(new LineSize());
|
||||
public static final ScissorsManager TESTER = new ScissorsManager(100);
|
||||
public static final Counter[] COUNTERS = Counter.createCounters(4);
|
||||
public static final ViewPortStack VIEW_PORT = new ViewPortStack();
|
||||
|
||||
public static <T extends IGLState> T addState(T state)
|
||||
{
|
||||
ALL_STATES.add(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
public static void onFrameEnded()
|
||||
{
|
||||
for(int i = 0,m=COUNTERS.length;i<m;i++)
|
||||
{
|
||||
COUNTERS[i].onFinished();
|
||||
}
|
||||
for(int i = 0;i<ALL_STATES.size();i++)
|
||||
{
|
||||
ALL_STATES.get(i).cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawArrays(int mode, int count)
|
||||
{
|
||||
drawArrays(mode, 0, count);
|
||||
}
|
||||
|
||||
public static void drawArrays(int mode, int first, int count)
|
||||
{
|
||||
addVerties(mode, count);
|
||||
GL11.glDrawArrays(mode, first, count);
|
||||
}
|
||||
|
||||
public static void drawElements(int mode, int count, int type, long indices)
|
||||
{
|
||||
addVerties(mode, count);
|
||||
GL11.glDrawElements(mode, count, type, indices);
|
||||
}
|
||||
|
||||
public static void drawElements(int mode, IntBuffer buffer)
|
||||
{
|
||||
addVerties(mode, buffer.remaining());
|
||||
GL11.glDrawElements(mode, buffer);
|
||||
}
|
||||
|
||||
public static void drawArraysInstanced(int mode, int first, int count, int instanced)
|
||||
{
|
||||
addVerties(mode, count * instanced);
|
||||
GL31.glDrawArraysInstanced(mode, first, count, instanced);
|
||||
}
|
||||
|
||||
public static void drawElementsInstanced(int mode, int count, int type, long indices, int instanced)
|
||||
{
|
||||
addVerties(mode, count * instanced);
|
||||
GL31.glDrawElementsInstanced(mode, count, type, indices, instanced);
|
||||
}
|
||||
|
||||
public static void drawElementsIndirect(int mode, int type, long pointer, int drawCount, int stride)
|
||||
{
|
||||
addVerties(mode, drawAmount(pointer, drawCount));
|
||||
GL44.glMultiDrawElementsIndirect(mode, type, pointer, drawCount, stride);
|
||||
}
|
||||
|
||||
static int drawAmount(long pointer, int amount)
|
||||
{
|
||||
int total = 0;
|
||||
return total;
|
||||
}
|
||||
|
||||
static void addVerties(int mode, int count)
|
||||
{
|
||||
COUNTERS[0].add(count);
|
||||
switch(mode)
|
||||
{
|
||||
case GL11.GL_POINTS:
|
||||
COUNTERS[1].add(count);
|
||||
break;
|
||||
case GL11.GL_LINES:
|
||||
COUNTERS[2].add(count / 2);
|
||||
break;
|
||||
case GL11.GL_LINE_LOOP:
|
||||
COUNTERS[2].add((count + 2) / 2);
|
||||
break;
|
||||
case GL11.GL_LINE_STRIP:
|
||||
COUNTERS[2].add(count - 1);
|
||||
break;
|
||||
case GL11.GL_TRIANGLES:
|
||||
COUNTERS[3].add(count / 3);
|
||||
break;
|
||||
case GL11.GL_TRIANGLE_STRIP:
|
||||
COUNTERS[3].add(count - 2);
|
||||
break;
|
||||
case GL11.GL_TRIANGLE_FAN:
|
||||
COUNTERS[3].add(count - 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.utils;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
import org.lwjgl.opengl.GL31;
|
||||
import org.lwjgl.opengl.GL44;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.coreengine.rendering.utils.states.BlendState;
|
||||
import speiger.src.coreengine.rendering.utils.states.CullState;
|
||||
import speiger.src.coreengine.rendering.utils.states.GLProvoking;
|
||||
import speiger.src.coreengine.rendering.utils.states.GLState;
|
||||
import speiger.src.coreengine.rendering.utils.states.GLWireFrame;
|
||||
import speiger.src.coreengine.rendering.utils.states.IGLState;
|
||||
import speiger.src.coreengine.rendering.utils.states.LineSize;
|
||||
import speiger.src.coreengine.rendering.utils.states.PointSize;
|
||||
import speiger.src.coreengine.utils.counters.averager.Counter;
|
||||
|
||||
public class GLUtils
|
||||
{
|
||||
static final List<IGLState> ALL_STATES = new ObjectArrayList<>();
|
||||
public static final GLState MULTI_SAMPLING = addState(new GLState(GL13.GL_MULTISAMPLE, false));
|
||||
public static final GLState WIRE_FRAME = addState(new GLWireFrame());
|
||||
public static final GLState PROVOKING_VERTEX = addState(new GLProvoking());
|
||||
public static final GLState DEBTH_TEST = addState(new GLState(GL11.GL_DEPTH_TEST, false));
|
||||
public static final CullState CULL_FACE = addState(new CullState(GL11.GL_BACK));
|
||||
public static final BlendState BLEND = addState(new BlendState());
|
||||
public static final GLState CLIP_PLANE0 = addState(new GLState(GL11.GL_CLIP_PLANE0, false));
|
||||
public static final PointSize POINT_SIZE = addState(new PointSize());
|
||||
public static final LineSize LINE_SIZE = addState(new LineSize());
|
||||
public static final ScissorsManager TESTER = new ScissorsManager(100);
|
||||
public static final Counter[] COUNTERS = Counter.createCounters(4);
|
||||
public static final ViewPortStack VIEW_PORT = new ViewPortStack();
|
||||
|
||||
public static <T extends IGLState> T addState(T state)
|
||||
{
|
||||
ALL_STATES.add(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
public static void reapplyState()
|
||||
{
|
||||
for(int i = 0;i<ALL_STATES.size();i++)
|
||||
{
|
||||
ALL_STATES.get(i).reapply();
|
||||
}
|
||||
}
|
||||
|
||||
public static void onFrameEnded()
|
||||
{
|
||||
for(int i = 0,m=COUNTERS.length;i<m;i++)
|
||||
{
|
||||
COUNTERS[i].onFinished();
|
||||
}
|
||||
for(int i = 0;i<ALL_STATES.size();i++)
|
||||
{
|
||||
ALL_STATES.get(i).cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawArrays(int mode, int count)
|
||||
{
|
||||
drawArrays(mode, 0, count);
|
||||
}
|
||||
|
||||
public static void drawArrays(int mode, int first, int count)
|
||||
{
|
||||
addVerties(mode, count);
|
||||
GL11.glDrawArrays(mode, first, count);
|
||||
}
|
||||
|
||||
public static void drawElements(int mode, int count, int type, long indices)
|
||||
{
|
||||
addVerties(mode, count);
|
||||
GL11.glDrawElements(mode, count, type, indices);
|
||||
}
|
||||
|
||||
public static void drawElements(int mode, IntBuffer buffer)
|
||||
{
|
||||
addVerties(mode, buffer.remaining());
|
||||
GL11.glDrawElements(mode, buffer);
|
||||
}
|
||||
|
||||
public static void drawArraysInstanced(int mode, int first, int count, int instanced)
|
||||
{
|
||||
addVerties(mode, count * instanced);
|
||||
GL31.glDrawArraysInstanced(mode, first, count, instanced);
|
||||
}
|
||||
|
||||
public static void drawElementsInstanced(int mode, int count, int type, long indices, int instanced)
|
||||
{
|
||||
addVerties(mode, count * instanced);
|
||||
GL31.glDrawElementsInstanced(mode, count, type, indices, instanced);
|
||||
}
|
||||
|
||||
public static void drawElementsIndirect(int mode, int type, long pointer, int drawCount, int stride)
|
||||
{
|
||||
addVerties(mode, drawAmount(pointer, drawCount));
|
||||
GL44.glMultiDrawElementsIndirect(mode, type, pointer, drawCount, stride);
|
||||
}
|
||||
|
||||
static int drawAmount(long pointer, int amount)
|
||||
{
|
||||
int total = 0;
|
||||
return total;
|
||||
}
|
||||
|
||||
static void addVerties(int mode, int count)
|
||||
{
|
||||
COUNTERS[0].add(count);
|
||||
switch(mode)
|
||||
{
|
||||
case GL11.GL_POINTS:
|
||||
COUNTERS[1].add(count);
|
||||
break;
|
||||
case GL11.GL_LINES:
|
||||
COUNTERS[2].add(count / 2);
|
||||
break;
|
||||
case GL11.GL_LINE_LOOP:
|
||||
COUNTERS[2].add((count + 2) / 2);
|
||||
break;
|
||||
case GL11.GL_LINE_STRIP:
|
||||
COUNTERS[2].add(count - 1);
|
||||
break;
|
||||
case GL11.GL_TRIANGLES:
|
||||
COUNTERS[3].add(count / 3);
|
||||
break;
|
||||
case GL11.GL_TRIANGLE_STRIP:
|
||||
COUNTERS[3].add(count - 2);
|
||||
break;
|
||||
case GL11.GL_TRIANGLE_FAN:
|
||||
COUNTERS[3].add(count - 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,248 +1,248 @@
|
|||
package speiger.src.coreengine.rendering.utils;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import speiger.src.coreengine.rendering.input.window.IWindowListener;
|
||||
import speiger.src.coreengine.rendering.input.window.Window;
|
||||
import speiger.src.coreengine.utils.helpers.FileUtils;
|
||||
import speiger.src.coreengine.utils.io.GifWriter;
|
||||
|
||||
public class ScreenshotHandler implements IWindowListener
|
||||
{
|
||||
public static final DateTimeFormatter FILE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss");
|
||||
public static final DateTimeFormatter FOLDER_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM");
|
||||
static final ThreadPoolExecutor FACTORY = (ThreadPoolExecutor)Executors.newFixedThreadPool(1);
|
||||
|
||||
File folder;
|
||||
int width;
|
||||
int height;
|
||||
ByteBuffer buffer;
|
||||
GifRecorder recorder;
|
||||
Supplier<BufferedImage> imageProvider = this::getData;
|
||||
|
||||
public ScreenshotHandler(File helper)
|
||||
{
|
||||
FACTORY.setKeepAliveTime(1, TimeUnit.SECONDS);
|
||||
FACTORY.allowCoreThreadTimeOut(true);
|
||||
folder = new File(helper, "Screenshots");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowChanged(Window window)
|
||||
{
|
||||
width = window.getWidth();
|
||||
height = window.getHeight();
|
||||
if(buffer != null)
|
||||
{
|
||||
MemoryUtil.memFree(buffer);
|
||||
buffer = null;
|
||||
}
|
||||
buffer = MemoryUtil.memAlloc(width * height * 4);
|
||||
}
|
||||
|
||||
public void screenShot()
|
||||
{
|
||||
ZonedDateTime time = ZonedDateTime.now();
|
||||
File subFolder = new File(folder, time.format(FOLDER_FORMAT));
|
||||
FileUtils.ensureFolder(subFolder);
|
||||
try
|
||||
{
|
||||
ImageIO.write(getScreenShot(), "png", new File(subFolder, "Screenshot_"+time.format(FILE_FORMAT)+".png"));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRecording()
|
||||
{
|
||||
return recorder != null && !recorder.isFinished();
|
||||
}
|
||||
|
||||
public void toggleRecording()
|
||||
{
|
||||
if(isRecording())
|
||||
{
|
||||
stopRecording();
|
||||
}
|
||||
else
|
||||
{
|
||||
startRecording();
|
||||
}
|
||||
}
|
||||
|
||||
//Undefined time recording
|
||||
public void startRecording()
|
||||
{
|
||||
record("Capture_"+ZonedDateTime.now().format(FILE_FORMAT)+".gif", 15, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public void record(String fileName, int fps, int time)
|
||||
{
|
||||
if(recorder == null)
|
||||
{
|
||||
File subFolder = new File(folder, ZonedDateTime.now().format(FOLDER_FORMAT));
|
||||
FileUtils.ensureFolder(subFolder);
|
||||
recorder = new GifRecorder(new File(subFolder, fileName), fps, time);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopRecording()
|
||||
{
|
||||
if(recorder != null)
|
||||
{
|
||||
recorder.finishPic();
|
||||
recorder = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
if(recorder != null)
|
||||
{
|
||||
recorder.tick(imageProvider);
|
||||
if(recorder.isFinished())
|
||||
{
|
||||
recorder.finishPic();
|
||||
recorder = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedImage getData()
|
||||
{
|
||||
buffer.clear();
|
||||
GL11.glReadBuffer(GL11.GL_FRONT);
|
||||
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
|
||||
for(int x = 0;x < width;x++)
|
||||
{
|
||||
for(int y = 0;y < height;y++)
|
||||
{
|
||||
int i = (x + (width * y)) * 4;
|
||||
int r = buffer.get(i) & 0xFF;
|
||||
int g = buffer.get(i + 1) & 0xFF;
|
||||
int b = buffer.get(i + 2) & 0xFF;
|
||||
data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
public BufferedImage getScreenShot()
|
||||
{
|
||||
buffer.clear();
|
||||
GL11.glReadBuffer(GL11.GL_FRONT);
|
||||
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
|
||||
for(int x = 0;x < width;x++)
|
||||
{
|
||||
for(int y = 0;y < height;y++)
|
||||
{
|
||||
int i = (x + (width * y)) * 4;
|
||||
int r = buffer.get(i) & 0xFF;
|
||||
int g = buffer.get(i + 1) & 0xFF;
|
||||
int b = buffer.get(i + 2) & 0xFF;
|
||||
data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
public void cleanup()
|
||||
{
|
||||
if(buffer != null)
|
||||
{
|
||||
MemoryUtil.memFree(buffer);
|
||||
buffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GifRecorder
|
||||
{
|
||||
GifWriter writer;
|
||||
long timeBetweenFrames;
|
||||
long lastTime = -1L;
|
||||
long freeTime;
|
||||
int totalPics;
|
||||
|
||||
public GifRecorder(File file, int fps, int time)
|
||||
{
|
||||
int ms = 1000 / fps;
|
||||
writer = GifWriter.create(file, BufferedImage.TYPE_INT_ARGB, ms);
|
||||
timeBetweenFrames = ms * 1000000L;
|
||||
freeTime = ms * 1000000L;
|
||||
totalPics = fps * time;
|
||||
}
|
||||
|
||||
public void tick(Supplier<BufferedImage> supply)
|
||||
{
|
||||
if(lastTime == -1L)
|
||||
{
|
||||
totalPics--;
|
||||
insert(supply.get());
|
||||
lastTime = System.nanoTime();
|
||||
return;
|
||||
}
|
||||
long time = System.nanoTime();
|
||||
long happend = time - lastTime;
|
||||
lastTime = time;
|
||||
freeTime -= happend;
|
||||
if(freeTime <= 0)
|
||||
{
|
||||
freeTime += timeBetweenFrames;
|
||||
insert(supply.get());
|
||||
totalPics--;
|
||||
}
|
||||
}
|
||||
|
||||
private void insert(final BufferedImage newBuffer)
|
||||
{
|
||||
FACTORY.execute(new Runnable(){
|
||||
BufferedImage buffer = newBuffer;
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if(writer != null)
|
||||
{
|
||||
writer.insertPicture(buffer);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isFinished()
|
||||
{
|
||||
return totalPics <= 0;
|
||||
}
|
||||
|
||||
public void finishPic()
|
||||
{
|
||||
FACTORY.execute(new Runnable(){
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
writer.close();
|
||||
writer = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.utils;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import speiger.src.coreengine.rendering.input.window.IWindowListener;
|
||||
import speiger.src.coreengine.rendering.input.window.Window;
|
||||
import speiger.src.coreengine.utils.helpers.FileUtils;
|
||||
import speiger.src.coreengine.utils.io.GifWriter;
|
||||
|
||||
public class ScreenshotHandler implements IWindowListener
|
||||
{
|
||||
public static final DateTimeFormatter FILE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss");
|
||||
public static final DateTimeFormatter FOLDER_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM");
|
||||
static final ThreadPoolExecutor FACTORY = (ThreadPoolExecutor)Executors.newFixedThreadPool(1);
|
||||
|
||||
File folder;
|
||||
int width;
|
||||
int height;
|
||||
ByteBuffer buffer;
|
||||
GifRecorder recorder;
|
||||
Supplier<BufferedImage> imageProvider = this::getData;
|
||||
|
||||
public ScreenshotHandler(File helper)
|
||||
{
|
||||
FACTORY.setKeepAliveTime(1, TimeUnit.SECONDS);
|
||||
FACTORY.allowCoreThreadTimeOut(true);
|
||||
folder = new File(helper, "Screenshots");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowChanged(Window window)
|
||||
{
|
||||
width = window.getWidth();
|
||||
height = window.getHeight();
|
||||
if(buffer != null)
|
||||
{
|
||||
MemoryUtil.memFree(buffer);
|
||||
buffer = null;
|
||||
}
|
||||
buffer = MemoryUtil.memAlloc(width * height * 4);
|
||||
}
|
||||
|
||||
public void screenShot()
|
||||
{
|
||||
ZonedDateTime time = ZonedDateTime.now();
|
||||
File subFolder = new File(folder, time.format(FOLDER_FORMAT));
|
||||
FileUtils.ensureFolder(subFolder);
|
||||
try
|
||||
{
|
||||
ImageIO.write(getScreenShot(), "png", new File(subFolder, "Screenshot_"+time.format(FILE_FORMAT)+".png"));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRecording()
|
||||
{
|
||||
return recorder != null && !recorder.isFinished();
|
||||
}
|
||||
|
||||
public void toggleRecording()
|
||||
{
|
||||
if(isRecording())
|
||||
{
|
||||
stopRecording();
|
||||
}
|
||||
else
|
||||
{
|
||||
startRecording();
|
||||
}
|
||||
}
|
||||
|
||||
//Undefined time recording
|
||||
public void startRecording()
|
||||
{
|
||||
record("Capture_"+ZonedDateTime.now().format(FILE_FORMAT)+".gif", 15, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public void record(String fileName, int fps, int time)
|
||||
{
|
||||
if(recorder == null)
|
||||
{
|
||||
File subFolder = new File(folder, ZonedDateTime.now().format(FOLDER_FORMAT));
|
||||
FileUtils.ensureFolder(subFolder);
|
||||
recorder = new GifRecorder(new File(subFolder, fileName), fps, time);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopRecording()
|
||||
{
|
||||
if(recorder != null)
|
||||
{
|
||||
recorder.finishPic();
|
||||
recorder = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
if(recorder != null)
|
||||
{
|
||||
recorder.tick(imageProvider);
|
||||
if(recorder.isFinished())
|
||||
{
|
||||
recorder.finishPic();
|
||||
recorder = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedImage getData()
|
||||
{
|
||||
buffer.clear();
|
||||
GL11.glReadBuffer(GL11.GL_FRONT);
|
||||
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
|
||||
for(int x = 0;x < width;x++)
|
||||
{
|
||||
for(int y = 0;y < height;y++)
|
||||
{
|
||||
int i = (x + (width * y)) * 4;
|
||||
int r = buffer.get(i) & 0xFF;
|
||||
int g = buffer.get(i + 1) & 0xFF;
|
||||
int b = buffer.get(i + 2) & 0xFF;
|
||||
data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
public BufferedImage getScreenShot()
|
||||
{
|
||||
buffer.clear();
|
||||
GL11.glReadBuffer(GL11.GL_FRONT);
|
||||
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
int[] data = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
|
||||
for(int x = 0;x < width;x++)
|
||||
{
|
||||
for(int y = 0;y < height;y++)
|
||||
{
|
||||
int i = (x + (width * y)) * 4;
|
||||
int r = buffer.get(i) & 0xFF;
|
||||
int g = buffer.get(i + 1) & 0xFF;
|
||||
int b = buffer.get(i + 2) & 0xFF;
|
||||
data[x + (width * (height - (y + 1)))] = (0xFF << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
public void cleanup()
|
||||
{
|
||||
if(buffer != null)
|
||||
{
|
||||
MemoryUtil.memFree(buffer);
|
||||
buffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GifRecorder
|
||||
{
|
||||
GifWriter writer;
|
||||
long timeBetweenFrames;
|
||||
long lastTime = -1L;
|
||||
long freeTime;
|
||||
int totalPics;
|
||||
|
||||
public GifRecorder(File file, int fps, int time)
|
||||
{
|
||||
int ms = 1000 / fps;
|
||||
writer = GifWriter.create(file, BufferedImage.TYPE_INT_ARGB, ms);
|
||||
timeBetweenFrames = ms * 1000000L;
|
||||
freeTime = ms * 1000000L;
|
||||
totalPics = fps * time;
|
||||
}
|
||||
|
||||
public void tick(Supplier<BufferedImage> supply)
|
||||
{
|
||||
if(lastTime == -1L)
|
||||
{
|
||||
totalPics--;
|
||||
insert(supply.get());
|
||||
lastTime = System.nanoTime();
|
||||
return;
|
||||
}
|
||||
long time = System.nanoTime();
|
||||
long happend = time - lastTime;
|
||||
lastTime = time;
|
||||
freeTime -= happend;
|
||||
if(freeTime <= 0)
|
||||
{
|
||||
freeTime += timeBetweenFrames;
|
||||
insert(supply.get());
|
||||
totalPics--;
|
||||
}
|
||||
}
|
||||
|
||||
private void insert(final BufferedImage newBuffer)
|
||||
{
|
||||
FACTORY.execute(new Runnable(){
|
||||
BufferedImage buffer = newBuffer;
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if(writer != null)
|
||||
{
|
||||
writer.insertPicture(buffer);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isFinished()
|
||||
{
|
||||
return totalPics <= 0;
|
||||
}
|
||||
|
||||
public void finishPic()
|
||||
{
|
||||
FACTORY.execute(new Runnable(){
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
writer.close();
|
||||
writer = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,44 @@
|
|||
package speiger.src.coreengine.rendering.utils.states;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class BlendState extends GLState
|
||||
{
|
||||
int src;
|
||||
int func;
|
||||
|
||||
public BlendState()
|
||||
{
|
||||
super(GL11.GL_BLEND, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlendState push(boolean newValue)
|
||||
{
|
||||
super.push(newValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlendState setFunction(int src, int func)
|
||||
{
|
||||
if(this.src != src && this.func != func)
|
||||
{
|
||||
this.src = src;
|
||||
this.func = func;
|
||||
GL11.glBlendFunc(src, func);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setDefault()
|
||||
{
|
||||
setFunction(GL11.GL_ONE, GL11.GL_ONE);
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.utils.states;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class BlendState extends GLState
|
||||
{
|
||||
int src;
|
||||
int func;
|
||||
|
||||
public BlendState()
|
||||
{
|
||||
super(GL11.GL_BLEND, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlendState push(boolean newValue)
|
||||
{
|
||||
super.push(newValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlendState setFunction(int src, int func)
|
||||
{
|
||||
if(this.src != src && this.func != func)
|
||||
{
|
||||
this.src = src;
|
||||
this.func = func;
|
||||
GL11.glBlendFunc(src, func);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reapply()
|
||||
{
|
||||
super.reapply();
|
||||
GL11.glBlendFunc(src, func);
|
||||
}
|
||||
|
||||
public void setDefault()
|
||||
{
|
||||
setFunction(GL11.GL_ONE, GL11.GL_ONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,40 @@
|
|||
package speiger.src.coreengine.rendering.utils.states;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class CullState extends GLState
|
||||
{
|
||||
int type;
|
||||
|
||||
public CullState(int defaultState)
|
||||
{
|
||||
super(GL11.GL_CULL_FACE, false);
|
||||
type = defaultState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CullState push(boolean newValue)
|
||||
{
|
||||
super.push(newValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setCullType(int type)
|
||||
{
|
||||
if(this.type != type)
|
||||
{
|
||||
this.type = type;
|
||||
if(lastState)
|
||||
{
|
||||
GL11.glCullFace(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.utils.states;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class CullState extends GLState
|
||||
{
|
||||
int type;
|
||||
|
||||
public CullState(int defaultState)
|
||||
{
|
||||
super(GL11.GL_CULL_FACE, false);
|
||||
type = defaultState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CullState push(boolean newValue)
|
||||
{
|
||||
super.push(newValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setCullType(int type)
|
||||
{
|
||||
if(this.type != type)
|
||||
{
|
||||
this.type = type;
|
||||
if(lastState)
|
||||
{
|
||||
GL11.glCullFace(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reapply()
|
||||
{
|
||||
super.reapply();
|
||||
GL11.glCullFace(type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,58 +1,59 @@
|
|||
package speiger.src.coreengine.rendering.utils.states;
|
||||
|
||||
import speiger.src.collections.floats.lists.FloatArrayList;
|
||||
import speiger.src.collections.floats.lists.FloatList;
|
||||
|
||||
public abstract class FloatState implements IGLState
|
||||
{
|
||||
protected final float defaultValue;
|
||||
protected FloatList states = new FloatArrayList();
|
||||
|
||||
public FloatState(float defaultValue)
|
||||
{
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public void push(float newValue)
|
||||
{
|
||||
if((states.isEmpty() && equalsNot(newValue, defaultValue)) || (states.size() > 0 && equalsNot(states.getFloat(states.size()-1), newValue)))
|
||||
{
|
||||
setValue(newValue);
|
||||
}
|
||||
states.add(newValue);
|
||||
}
|
||||
|
||||
public void pop()
|
||||
{
|
||||
if(states.isEmpty()) throw new IllegalStateException("State is already reset");
|
||||
if(states.size() == 1 && equalsNot(defaultValue, states.getFloat(0)))
|
||||
{
|
||||
setValue(defaultValue);
|
||||
}
|
||||
else if(states.size() > 1 && equalsNot(states.getFloat(states.size()-2), states.getFloat(states.size()-1)))
|
||||
{
|
||||
setValue(states.getFloat(states.size()-2));
|
||||
}
|
||||
states.removeFloat(states.size()-1);
|
||||
}
|
||||
|
||||
protected abstract void setValue(float value);
|
||||
|
||||
protected abstract String getName();
|
||||
|
||||
protected boolean equalsNot(float key, float value)
|
||||
{
|
||||
return Float.floatToIntBits(key) != Float.floatToIntBits(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
if(states.size() > 1)
|
||||
{
|
||||
float value = states.getFloat(states.size()-1);
|
||||
states.clear();
|
||||
states.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.utils.states;
|
||||
|
||||
import speiger.src.collections.floats.collections.FloatStack;
|
||||
import speiger.src.collections.floats.lists.FloatArrayList;
|
||||
|
||||
public abstract class FloatState implements IGLState
|
||||
{
|
||||
protected final float defaultValue;
|
||||
protected FloatStack states = new FloatArrayList();
|
||||
|
||||
public FloatState(float defaultValue)
|
||||
{
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public void push(float newValue)
|
||||
{
|
||||
if((states.isEmpty() && equalsNot(newValue, defaultValue)) || (states.size() > 0 && equalsNot(states.top(), newValue)))
|
||||
{
|
||||
setValue(newValue);
|
||||
}
|
||||
states.push(newValue);
|
||||
}
|
||||
|
||||
public void pop()
|
||||
{
|
||||
if(states.isEmpty()) throw new IllegalStateException("State is already reset");
|
||||
float prev = states.pop();
|
||||
if(states.isEmpty() && equalsNot(defaultValue, prev)) setValue(defaultValue);
|
||||
else if(!states.isEmpty() && equalsNot(states.top(), prev)) setValue(states.top());
|
||||
}
|
||||
|
||||
protected abstract void setValue(float value);
|
||||
|
||||
protected abstract String getName();
|
||||
|
||||
protected boolean equalsNot(float key, float value)
|
||||
{
|
||||
return Float.floatToIntBits(key) != Float.floatToIntBits(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reapply()
|
||||
{
|
||||
if(states.isEmpty()) setValue(defaultValue);
|
||||
else setValue(states.top());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
if(states.size() > 1)
|
||||
{
|
||||
float value = states.top();
|
||||
states.clear();
|
||||
states.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,65 +1,72 @@
|
|||
package speiger.src.coreengine.rendering.utils.states;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class GLState implements IGLState
|
||||
{
|
||||
final int id;
|
||||
protected final boolean defaultValue;
|
||||
protected final BitSet memory = new BitSet();
|
||||
protected int index = -1;
|
||||
protected boolean lastState;
|
||||
|
||||
public GLState(int id, boolean defaultValue)
|
||||
{
|
||||
this.id = id;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public GLState push(boolean newValue)
|
||||
{
|
||||
if((index < 0 && newValue != defaultValue) || (index >= 0 && memory.get(index) != newValue))
|
||||
{
|
||||
setValue(newValue);
|
||||
}
|
||||
memory.set(++index, newValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void pop()
|
||||
{
|
||||
if(index < 0) throw new IllegalStateException("State is already reset");
|
||||
if(index == 0 && defaultValue != memory.get(0))
|
||||
{
|
||||
setValue(defaultValue);
|
||||
}
|
||||
else if(index > 0 && memory.get(index-1) != memory.get(index))
|
||||
{
|
||||
setValue(memory.get(index-1));
|
||||
}
|
||||
index--;
|
||||
}
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return index < 0 ? defaultValue : memory.get(index);
|
||||
}
|
||||
|
||||
protected void setValue(boolean value)
|
||||
{
|
||||
if(value) GL11.glEnable(id);
|
||||
else GL11.glDisable(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
if(index > 0)
|
||||
{
|
||||
memory.set(0, memory.get(index));
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.rendering.utils.states;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class GLState implements IGLState
|
||||
{
|
||||
final int id;
|
||||
protected final boolean defaultValue;
|
||||
protected final BitSet memory = new BitSet();
|
||||
protected int index = -1;
|
||||
protected boolean lastState;
|
||||
|
||||
public GLState(int id, boolean defaultValue)
|
||||
{
|
||||
this.id = id;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public GLState push(boolean newValue)
|
||||
{
|
||||
if((index < 0 && newValue != defaultValue) || (index >= 0 && memory.get(index) != newValue))
|
||||
{
|
||||
setValue(newValue);
|
||||
}
|
||||
memory.set(++index, newValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void pop()
|
||||
{
|
||||
if(index < 0) throw new IllegalStateException("State is already reset");
|
||||
if(index == 0 && defaultValue != memory.get(0))
|
||||
{
|
||||
setValue(defaultValue);
|
||||
}
|
||||
else if(index > 0 && memory.get(index-1) != memory.get(index))
|
||||
{
|
||||
setValue(memory.get(index-1));
|
||||
}
|
||||
index--;
|
||||
}
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return index < 0 ? defaultValue : memory.get(index);
|
||||
}
|
||||
|
||||
protected void setValue(boolean value)
|
||||
{
|
||||
if(value) GL11.glEnable(id);
|
||||
else GL11.glDisable(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reapply()
|
||||
{
|
||||
if(index < 0) setValue(defaultValue);
|
||||
else setValue(memory.get(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
if(index > 0)
|
||||
{
|
||||
memory.set(0, memory.get(index));
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package speiger.src.coreengine.rendering.utils.states;
|
||||
|
||||
public interface IGLState
|
||||
{
|
||||
public void cleanup();
|
||||
}
|
||||
package speiger.src.coreengine.rendering.utils.states;
|
||||
|
||||
public interface IGLState
|
||||
{
|
||||
public void cleanup();
|
||||
public void reapply();
|
||||
}
|
||||
|
|
|
@ -1,76 +1,80 @@
|
|||
package speiger.src.coreengine.utils.collections.pools;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.collections.objects.lists.ObjectList;
|
||||
import speiger.src.coreengine.utils.functions.Functions;
|
||||
|
||||
public class ThreadPool<T> implements IPool<T>
|
||||
{
|
||||
int cap;
|
||||
ObjectList<T> stack;
|
||||
Supplier<T> creator;
|
||||
Consumer<T> acceptor;
|
||||
|
||||
public ThreadPool(int size, Supplier<T> creator)
|
||||
{
|
||||
this(size, creator, Functions.getVoidConsumer());
|
||||
}
|
||||
|
||||
public ThreadPool(int size, Supplier<T> creator, Consumer<T> acceptor)
|
||||
{
|
||||
cap = size;
|
||||
stack = new ObjectArrayList<T>(size);
|
||||
this.creator = creator;
|
||||
this.acceptor = acceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void accept(T t)
|
||||
{
|
||||
if(stack.size() < cap)
|
||||
{
|
||||
stack.add(t);
|
||||
acceptor.accept(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void accept(T[] array)
|
||||
{
|
||||
stack.addAll(array, 0, Math.min(array.length, cap - stack.size()));
|
||||
for(int i = 0,m=Math.min(array.length, cap - stack.size());i<m;acceptor.accept(array[i++]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void accept(Collection<T> array)
|
||||
{
|
||||
Iterator<T> iter = array.iterator();
|
||||
for(int i = 0,m=Math.min(array.size(), cap - stack.size());i<m && iter.hasNext();i++)
|
||||
{
|
||||
T next = iter.next();
|
||||
stack.add(next);
|
||||
acceptor.accept(next);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized T get()
|
||||
{
|
||||
return stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized T[] get(T[] array)
|
||||
{
|
||||
for(int i = 0,m=array.length;i<m;i++)
|
||||
{
|
||||
array[i] = stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.utils.collections.pools;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.collections.objects.lists.ObjectList;
|
||||
import speiger.src.coreengine.utils.functions.Functions;
|
||||
|
||||
public class ThreadPool<T> implements IPool<T>
|
||||
{
|
||||
int cap;
|
||||
ObjectList<T> stack;
|
||||
Supplier<T> creator;
|
||||
Consumer<T> acceptor;
|
||||
|
||||
public ThreadPool(int size, Supplier<T> creator)
|
||||
{
|
||||
this(size, creator, Functions.getVoidConsumer());
|
||||
}
|
||||
|
||||
public ThreadPool(int size, Supplier<T> creator, Consumer<T> acceptor)
|
||||
{
|
||||
cap = size;
|
||||
stack = new ObjectArrayList<T>(size);
|
||||
this.creator = creator;
|
||||
this.acceptor = acceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void accept(T t)
|
||||
{
|
||||
if(stack.size() < cap)
|
||||
{
|
||||
stack.add(t);
|
||||
acceptor.accept(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void accept(T[] array)
|
||||
{
|
||||
int size = Math.min(array.length, cap - stack.size());
|
||||
if(size <= 0) return;
|
||||
stack.addAll(array, 0, size);
|
||||
for(int i = 0;i<size;acceptor.accept(array[i++]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void accept(Collection<T> array)
|
||||
{
|
||||
int size = Math.min(array.size(), cap - stack.size());
|
||||
if(size <= 0) return;
|
||||
Iterator<T> iter = array.iterator();
|
||||
for(int i = 0;i<size && iter.hasNext();i++)
|
||||
{
|
||||
T next = iter.next();
|
||||
stack.add(next);
|
||||
acceptor.accept(next);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized T get()
|
||||
{
|
||||
return stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized T[] get(T[] array)
|
||||
{
|
||||
for(int i = 0,m=array.length;i<m;i++)
|
||||
{
|
||||
array[i] = stack.isEmpty() ? creator.get() : stack.remove(stack.size() - 1);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,151 +1,151 @@
|
|||
package speiger.src.coreengine.utils.profiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import speiger.src.collections.longs.queues.LongArrayFIFOQueue;
|
||||
import speiger.src.collections.longs.queues.LongPriorityQueue;
|
||||
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
|
||||
import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
|
||||
import speiger.src.coreengine.rendering.utils.GLStamper;
|
||||
import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
|
||||
|
||||
public class GPUProfilerEntry implements IProfilerEntry
|
||||
{
|
||||
String name;
|
||||
String pathName;
|
||||
IProfiler owner;
|
||||
IProfilerEntry parent;
|
||||
List<IProfilerEntry> children = new ArrayList<IProfilerEntry>();
|
||||
int debth = 0;
|
||||
int totalTicks = 0;
|
||||
|
||||
long maxTime = Long.MIN_VALUE;
|
||||
long minTime = Long.MAX_VALUE;
|
||||
long average = 0L;
|
||||
LongPriorityQueue entries = new LongArrayFIFOQueue();
|
||||
long startTime = 0L;
|
||||
long currentTime = 0L;
|
||||
|
||||
ObjectPriorityDequeue<GLStamp> stamps = new ObjectArrayFIFOQueue<GLStamp>();
|
||||
|
||||
public GPUProfilerEntry(String name, IProfiler owner)
|
||||
{
|
||||
this.name = name;
|
||||
pathName = name;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void addChild(GPUProfilerEntry child)
|
||||
{
|
||||
if(child != null)
|
||||
{
|
||||
children.add(child);
|
||||
child.setParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void setParent(GPUProfilerEntry parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
debth = parent.debth + 1;
|
||||
pathName = parent.pathName+"/"+name;
|
||||
}
|
||||
|
||||
public void start()
|
||||
{
|
||||
stamps.enqueue(GLStamper.INSTANCE.createStamp(owner.getName()).start());
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
stamps.last().stop();
|
||||
}
|
||||
|
||||
public void onFrameFinished(boolean end)
|
||||
{
|
||||
while(!stamps.isEmpty() && stamps.first().isFinished())
|
||||
{
|
||||
GLStamp stamp = stamps.dequeue();
|
||||
currentTime += stamp.getResult();
|
||||
stamp.release();
|
||||
}
|
||||
average += currentTime;
|
||||
entries.enqueue(currentTime);
|
||||
if(entries.size() > 20)
|
||||
{
|
||||
average -= entries.dequeue();
|
||||
}
|
||||
currentTime = average / entries.size();
|
||||
minTime = Math.min(minTime, currentTime);
|
||||
maxTime = Math.max(maxTime, currentTime);
|
||||
currentTime = 0;
|
||||
if(end && totalTicks++ >= 10)
|
||||
{
|
||||
minTime = currentTime;
|
||||
maxTime = currentTime;
|
||||
totalTicks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathName()
|
||||
{
|
||||
return pathName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDebth()
|
||||
{
|
||||
return debth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfiler getOwner()
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfilerEntry getParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount()
|
||||
{
|
||||
return children.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfilerEntry getChild(int index)
|
||||
{
|
||||
return children.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMinTime()
|
||||
{
|
||||
return minTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNanoTime()
|
||||
{
|
||||
return entries.isEmpty() ? 0L : average / entries.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxTime()
|
||||
{
|
||||
return maxTime;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.utils.profiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import speiger.src.collections.longs.queues.LongArrayFIFOQueue;
|
||||
import speiger.src.collections.longs.queues.LongPriorityQueue;
|
||||
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
|
||||
import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
|
||||
import speiger.src.coreengine.rendering.utils.GLStamper;
|
||||
import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
|
||||
|
||||
public class GPUProfilerEntry implements IProfilerEntry
|
||||
{
|
||||
String name;
|
||||
String pathName;
|
||||
IProfiler owner;
|
||||
IProfilerEntry parent;
|
||||
List<IProfilerEntry> children = new ArrayList<IProfilerEntry>();
|
||||
int debth = 0;
|
||||
int totalTicks = 0;
|
||||
|
||||
long maxTime = Long.MIN_VALUE;
|
||||
long minTime = Long.MAX_VALUE;
|
||||
long average = 0L;
|
||||
LongPriorityQueue entries = new LongArrayFIFOQueue();
|
||||
long startTime = 0L;
|
||||
long currentTime = 0L;
|
||||
|
||||
ObjectPriorityDequeue<GLStamp> stamps = new ObjectArrayFIFOQueue<GLStamp>();
|
||||
|
||||
public GPUProfilerEntry(String name, IProfiler owner)
|
||||
{
|
||||
this.name = name;
|
||||
pathName = name;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void addChild(GPUProfilerEntry child)
|
||||
{
|
||||
if(child != null)
|
||||
{
|
||||
children.add(child);
|
||||
child.setParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void setParent(GPUProfilerEntry parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
debth = parent.debth + 1;
|
||||
pathName = parent.pathName+"/"+name;
|
||||
}
|
||||
|
||||
public void start()
|
||||
{
|
||||
stamps.enqueue(GLStamper.INSTANCE.createStamp(owner.getName()).start());
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
stamps.last().stop();
|
||||
}
|
||||
|
||||
public void onFrameFinished(boolean end)
|
||||
{
|
||||
while(!stamps.isEmpty() && stamps.first().isFinished())
|
||||
{
|
||||
GLStamp stamp = stamps.dequeue();
|
||||
currentTime += stamp.getResult();
|
||||
stamp.release();
|
||||
}
|
||||
average += currentTime;
|
||||
entries.enqueue(currentTime);
|
||||
if(entries.size() > 100)
|
||||
{
|
||||
average -= entries.dequeue();
|
||||
}
|
||||
currentTime = average / entries.size();
|
||||
minTime = Math.min(minTime, currentTime);
|
||||
maxTime = Math.max(maxTime, currentTime);
|
||||
currentTime = 0;
|
||||
if(end && totalTicks++ >= 10)
|
||||
{
|
||||
minTime = currentTime;
|
||||
maxTime = currentTime;
|
||||
totalTicks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathName()
|
||||
{
|
||||
return pathName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDebth()
|
||||
{
|
||||
return debth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfiler getOwner()
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfilerEntry getParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount()
|
||||
{
|
||||
return children.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfilerEntry getChild(int index)
|
||||
{
|
||||
return children.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMinTime()
|
||||
{
|
||||
return minTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNanoTime()
|
||||
{
|
||||
return entries.isEmpty() ? 0L : average / entries.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxTime()
|
||||
{
|
||||
return maxTime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,163 +1,161 @@
|
|||
package speiger.src.coreengine.utils.profiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.ObjIntConsumer;
|
||||
|
||||
import speiger.src.coreengine.utils.helpers.TextUtil;
|
||||
|
||||
public interface IProfiler
|
||||
{
|
||||
|
||||
public String getName();
|
||||
|
||||
public IProfilerEntry getEntry(String name);
|
||||
|
||||
public long getTicksRan();
|
||||
|
||||
public void enable();
|
||||
|
||||
public void disable();
|
||||
|
||||
public default void setState(boolean enabled)
|
||||
{
|
||||
if(enabled)
|
||||
{
|
||||
enable();
|
||||
return;
|
||||
}
|
||||
disable();
|
||||
}
|
||||
|
||||
public boolean isEnabled();
|
||||
|
||||
public void addListener(ObjIntConsumer<IProfiler> listener);
|
||||
|
||||
public void removeListener(ObjIntConsumer<IProfiler> listener);
|
||||
|
||||
public IProfiler start(String name);
|
||||
|
||||
public IProfiler start(Class<?> clz);
|
||||
|
||||
public IProfiler stop();
|
||||
|
||||
public IProfiler next(String name);
|
||||
|
||||
public void onFrameEnded(boolean count);
|
||||
|
||||
public static interface IProfilerEntry
|
||||
{
|
||||
public String getName();
|
||||
|
||||
public default String getPathName()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
|
||||
public long getMinTime();
|
||||
|
||||
public long getNanoTime();
|
||||
|
||||
public long getMaxTime();
|
||||
|
||||
public int getDebth();
|
||||
|
||||
public int getChildCount();
|
||||
|
||||
public IProfilerEntry getChild(int index);
|
||||
|
||||
public IProfilerEntry getParent();
|
||||
|
||||
public IProfiler getOwner();
|
||||
|
||||
default long getTotalTime()
|
||||
{
|
||||
IProfilerEntry entry = this;
|
||||
while(entry.getParent() != null)
|
||||
{
|
||||
entry = entry.getParent();
|
||||
}
|
||||
return entry.getNanoTime();
|
||||
}
|
||||
|
||||
public default List<ProfilerData> getData()
|
||||
{
|
||||
List<ProfilerData> list = new ArrayList<ProfilerData>();
|
||||
long time = getNanoTime();
|
||||
long totalTime = getTotalTime();
|
||||
long used = 0L;
|
||||
for(int i = 0;i<getChildCount();i++)
|
||||
{
|
||||
IProfilerEntry child = getChild(i);
|
||||
long nanoTime = child.getNanoTime();
|
||||
used += nanoTime;
|
||||
double percent = (((double)nanoTime / (double)time) * 100D);
|
||||
double totalPercent = (((double)nanoTime / (double)totalTime) * 100D);
|
||||
list.add(new ProfilerData(child.getName(), nanoTime, percent, totalPercent));
|
||||
}
|
||||
if(used < time)
|
||||
{
|
||||
long nanoTime = time - used;
|
||||
double percent = (((double)nanoTime / (double)time) * 100D);
|
||||
double totalPercent = (((double)nanoTime / (double)totalTime) * 100D);
|
||||
list.add(new ProfilerData("Nameless", nanoTime, percent, totalPercent));
|
||||
}
|
||||
Collections.sort(list);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProfilerData implements Comparable<ProfilerData>
|
||||
{
|
||||
String name;
|
||||
int color;
|
||||
long nanoTime;
|
||||
double effect;
|
||||
double totalEffect;
|
||||
|
||||
public ProfilerData(String name, long time, double effect, double totalEffect)
|
||||
{
|
||||
this.name = name;
|
||||
color = TextUtil.getColorFromText(name);
|
||||
nanoTime = time;
|
||||
this.effect = effect;
|
||||
this.totalEffect = totalEffect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ProfilerData o)
|
||||
{
|
||||
if(o.nanoTime > nanoTime)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return o.nanoTime < nanoTime ? -1 : name.compareTo(o.name);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getColor()
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
public long getNanoTime()
|
||||
{
|
||||
return nanoTime;
|
||||
}
|
||||
|
||||
public double getEffect()
|
||||
{
|
||||
return effect;
|
||||
}
|
||||
|
||||
public double getTotalEffect()
|
||||
{
|
||||
return totalEffect;
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.utils.profiler;
|
||||
|
||||
import java.util.function.ObjIntConsumer;
|
||||
|
||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||
import speiger.src.collections.objects.lists.ObjectList;
|
||||
import speiger.src.coreengine.utils.helpers.TextUtil;
|
||||
|
||||
public interface IProfiler
|
||||
{
|
||||
public String getName();
|
||||
|
||||
public IProfilerEntry getEntry(String name);
|
||||
|
||||
public long getTicksRan();
|
||||
|
||||
public void enable();
|
||||
|
||||
public void disable();
|
||||
|
||||
public default void setState(boolean enabled)
|
||||
{
|
||||
if(enabled)
|
||||
{
|
||||
enable();
|
||||
return;
|
||||
}
|
||||
disable();
|
||||
}
|
||||
|
||||
public boolean isEnabled();
|
||||
|
||||
public void addListener(ObjIntConsumer<IProfiler> listener);
|
||||
|
||||
public void removeListener(ObjIntConsumer<IProfiler> listener);
|
||||
|
||||
public IProfiler start(String name);
|
||||
|
||||
public IProfiler start(Class<?> clz);
|
||||
|
||||
public IProfiler stop();
|
||||
|
||||
public IProfiler next(String name);
|
||||
|
||||
public void onFrameEnded(boolean count);
|
||||
|
||||
public static interface IProfilerEntry
|
||||
{
|
||||
public String getName();
|
||||
|
||||
public default String getPathName()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
|
||||
public long getMinTime();
|
||||
|
||||
public long getNanoTime();
|
||||
|
||||
public long getMaxTime();
|
||||
|
||||
public int getDebth();
|
||||
|
||||
public int getChildCount();
|
||||
|
||||
public IProfilerEntry getChild(int index);
|
||||
|
||||
public IProfilerEntry getParent();
|
||||
|
||||
public IProfiler getOwner();
|
||||
|
||||
default long getTotalTime()
|
||||
{
|
||||
IProfilerEntry entry = this;
|
||||
while(entry.getParent() != null)
|
||||
{
|
||||
entry = entry.getParent();
|
||||
}
|
||||
return entry.getNanoTime();
|
||||
}
|
||||
|
||||
public default ObjectList<ProfilerData> getData()
|
||||
{
|
||||
ObjectList<ProfilerData> list = new ObjectArrayList<>();
|
||||
long time = getNanoTime();
|
||||
long totalTime = getTotalTime();
|
||||
long used = 0L;
|
||||
for(int i = 0;i<getChildCount();i++)
|
||||
{
|
||||
IProfilerEntry child = getChild(i);
|
||||
long nanoTime = child.getNanoTime();
|
||||
used += nanoTime;
|
||||
double percent = (((double)nanoTime / (double)time) * 100D);
|
||||
double totalPercent = (((double)nanoTime / (double)totalTime) * 100D);
|
||||
list.add(new ProfilerData(child.getName(), nanoTime, percent, totalPercent));
|
||||
}
|
||||
if(used < time)
|
||||
{
|
||||
long nanoTime = time - used;
|
||||
double percent = (((double)nanoTime / (double)time) * 100D);
|
||||
double totalPercent = (((double)nanoTime / (double)totalTime) * 100D);
|
||||
list.add(new ProfilerData("self", nanoTime, percent, totalPercent));
|
||||
}
|
||||
list.sort(null);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProfilerData implements Comparable<ProfilerData>
|
||||
{
|
||||
String name;
|
||||
int color;
|
||||
long nanoTime;
|
||||
double effect;
|
||||
double totalEffect;
|
||||
|
||||
public ProfilerData(String name, long time, double effect, double totalEffect)
|
||||
{
|
||||
this.name = name;
|
||||
color = TextUtil.getColorFromText(name);
|
||||
nanoTime = time;
|
||||
this.effect = effect;
|
||||
this.totalEffect = totalEffect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ProfilerData o)
|
||||
{
|
||||
if(o.nanoTime > nanoTime)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return o.nanoTime < nanoTime ? -1 : name.compareTo(o.name);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getColor()
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
public long getNanoTime()
|
||||
{
|
||||
return nanoTime;
|
||||
}
|
||||
|
||||
public double getEffect()
|
||||
{
|
||||
return effect;
|
||||
}
|
||||
|
||||
public double getTotalEffect()
|
||||
{
|
||||
return totalEffect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,152 +1,152 @@
|
|||
package speiger.src.coreengine.utils.profiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import speiger.src.collections.longs.queues.LongArrayFIFOQueue;
|
||||
import speiger.src.collections.longs.queues.LongPriorityQueue;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
|
||||
|
||||
public class ProfilerEntry implements IProfilerEntry
|
||||
{
|
||||
String name;
|
||||
String pathName;
|
||||
IProfiler owner;
|
||||
IProfilerEntry parent;
|
||||
List<IProfilerEntry> children = new ArrayList<IProfilerEntry>();
|
||||
int debth = 0;
|
||||
int totalTicks = 0;
|
||||
|
||||
long maxTime = Long.MIN_VALUE;
|
||||
long minTime = Long.MAX_VALUE;
|
||||
long average = 0L;
|
||||
LongPriorityQueue entries = new LongArrayFIFOQueue();
|
||||
long startTime = 0L;
|
||||
long currentTime = 0L;
|
||||
boolean didTick = false;
|
||||
|
||||
public ProfilerEntry(String name, IProfiler owner)
|
||||
{
|
||||
this.name = name;
|
||||
pathName = name;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void addChild(ProfilerEntry child)
|
||||
{
|
||||
if(child != null)
|
||||
{
|
||||
children.add(child);
|
||||
child.setParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void setParent(ProfilerEntry parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
debth = parent.debth + 1;
|
||||
pathName = parent.pathName+"/"+name;
|
||||
}
|
||||
|
||||
public void start()
|
||||
{
|
||||
startTime = System.nanoTime();
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
currentTime += (System.nanoTime() - startTime);
|
||||
didTick = true;
|
||||
}
|
||||
|
||||
public void onFrameFinished(boolean end)
|
||||
{
|
||||
if(!didTick)
|
||||
{
|
||||
if(end && totalTicks++ >= 10)
|
||||
{
|
||||
minTime = 0;
|
||||
maxTime = 0;
|
||||
totalTicks = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
didTick = false;
|
||||
average += currentTime;
|
||||
entries.enqueue(currentTime);
|
||||
if(entries.size() > 20)
|
||||
{
|
||||
average -= entries.dequeue();
|
||||
}
|
||||
currentTime = average / entries.size();
|
||||
minTime = Math.min(minTime, currentTime);
|
||||
maxTime = Math.max(maxTime, currentTime);
|
||||
currentTime = 0;
|
||||
if(end && totalTicks++ >= 10)
|
||||
{
|
||||
minTime = currentTime;
|
||||
maxTime = currentTime;
|
||||
totalTicks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathName()
|
||||
{
|
||||
return pathName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMinTime()
|
||||
{
|
||||
return minTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNanoTime()
|
||||
{
|
||||
return entries.isEmpty() ? 0L : average / entries.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxTime()
|
||||
{
|
||||
return maxTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDebth()
|
||||
{
|
||||
return debth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount()
|
||||
{
|
||||
return children.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfilerEntry getChild(int index)
|
||||
{
|
||||
return children.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfilerEntry getParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfiler getOwner()
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.utils.profiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import speiger.src.collections.longs.queues.LongArrayFIFOQueue;
|
||||
import speiger.src.collections.longs.queues.LongPriorityQueue;
|
||||
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
|
||||
|
||||
public class ProfilerEntry implements IProfilerEntry
|
||||
{
|
||||
String name;
|
||||
String pathName;
|
||||
IProfiler owner;
|
||||
IProfilerEntry parent;
|
||||
List<IProfilerEntry> children = new ArrayList<IProfilerEntry>();
|
||||
int debth = 0;
|
||||
int totalTicks = 0;
|
||||
|
||||
long maxTime = Long.MIN_VALUE;
|
||||
long minTime = Long.MAX_VALUE;
|
||||
long average = 0L;
|
||||
LongPriorityQueue entries = new LongArrayFIFOQueue();
|
||||
long startTime = 0L;
|
||||
long currentTime = 0L;
|
||||
boolean didTick = false;
|
||||
|
||||
public ProfilerEntry(String name, IProfiler owner)
|
||||
{
|
||||
this.name = name;
|
||||
pathName = name;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void addChild(ProfilerEntry child)
|
||||
{
|
||||
if(child != null)
|
||||
{
|
||||
children.add(child);
|
||||
child.setParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void setParent(ProfilerEntry parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
debth = parent.debth + 1;
|
||||
pathName = parent.pathName+"/"+name;
|
||||
}
|
||||
|
||||
public void start()
|
||||
{
|
||||
startTime = System.nanoTime();
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
currentTime += (System.nanoTime() - startTime);
|
||||
didTick = true;
|
||||
}
|
||||
|
||||
public void onFrameFinished(boolean end)
|
||||
{
|
||||
if(!didTick)
|
||||
{
|
||||
if(end && totalTicks++ >= 10)
|
||||
{
|
||||
minTime = Long.MAX_VALUE;
|
||||
maxTime = Long.MIN_VALUE;
|
||||
totalTicks = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
didTick = false;
|
||||
average += currentTime;
|
||||
entries.enqueue(currentTime);
|
||||
if(entries.size() > 100)
|
||||
{
|
||||
average -= entries.dequeue();
|
||||
}
|
||||
currentTime = average / entries.size();
|
||||
minTime = Math.min(minTime, currentTime);
|
||||
maxTime = Math.max(maxTime, currentTime);
|
||||
currentTime = 0;
|
||||
if(end && totalTicks++ >= 10)
|
||||
{
|
||||
minTime = currentTime;
|
||||
maxTime = currentTime;
|
||||
totalTicks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathName()
|
||||
{
|
||||
return pathName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMinTime()
|
||||
{
|
||||
return minTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNanoTime()
|
||||
{
|
||||
return entries.isEmpty() ? 0L : average / entries.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxTime()
|
||||
{
|
||||
return maxTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDebth()
|
||||
{
|
||||
return debth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount()
|
||||
{
|
||||
return children.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfilerEntry getChild(int index)
|
||||
{
|
||||
return children.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfilerEntry getParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfiler getOwner()
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,146 +1,146 @@
|
|||
package speiger.src.coreengine.utils.tasks;
|
||||
|
||||
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
|
||||
import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
|
||||
import speiger.src.collections.objects.utils.ObjectPriorityQueues;
|
||||
import speiger.src.coreengine.utils.counters.timers.CountdownSync;
|
||||
|
||||
public class MainThreadTaskProcessor
|
||||
{
|
||||
ObjectPriorityDequeue<ITask> tasks = ObjectPriorityQueues.synchronize(new ObjectArrayFIFOQueue<ITask>());
|
||||
Watchdog watch;
|
||||
Thread watchThread;
|
||||
boolean running = false;
|
||||
long timeout;
|
||||
|
||||
public MainThreadTaskProcessor(long timeout, String name)
|
||||
{
|
||||
this.timeout = timeout;
|
||||
watch = new Watchdog(Thread.currentThread());
|
||||
watchThread = new Thread(watch, name+"-Thread-Watchdog");
|
||||
watchThread.start();
|
||||
}
|
||||
|
||||
public void setTimeout(long timeout)
|
||||
{
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public void addTask(ITask task)
|
||||
{
|
||||
tasks.enqueue(task);
|
||||
}
|
||||
|
||||
public void finishAllTasks()
|
||||
{
|
||||
if(tasks.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
running = true;
|
||||
while(!tasks.isEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
tasks.dequeue().execute();
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
running = false;
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
if(tasks.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
watch.unlock();
|
||||
running = true;
|
||||
boolean interrupted = false;
|
||||
while(!tasks.isEmpty() && !(interrupted |= Thread.interrupted()))
|
||||
{
|
||||
ITask task = tasks.dequeue();
|
||||
try
|
||||
{
|
||||
task.execute();
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{
|
||||
interrupted = true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(!task.isFinished())
|
||||
{
|
||||
tasks.enqueue(task);
|
||||
}
|
||||
}
|
||||
running = false;
|
||||
if(!interrupted)
|
||||
{
|
||||
watchThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void kill()
|
||||
{
|
||||
if(watchThread != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
watch.alive = false;
|
||||
watchThread.interrupt();
|
||||
watchThread = null;
|
||||
}
|
||||
|
||||
class Watchdog implements Runnable
|
||||
{
|
||||
Thread owner;
|
||||
boolean alive = true;
|
||||
CountdownSync timer = new CountdownSync();
|
||||
Object lock = new Object();
|
||||
|
||||
public Watchdog(Thread thread)
|
||||
{
|
||||
owner = thread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
while(alive)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized(lock)
|
||||
{
|
||||
lock.wait();
|
||||
}
|
||||
timer.sync(timeout);
|
||||
if(running)
|
||||
{
|
||||
owner.interrupt();
|
||||
}
|
||||
}
|
||||
catch(InterruptedException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
public void unlock()
|
||||
{
|
||||
synchronized(lock)
|
||||
{
|
||||
lock.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
package speiger.src.coreengine.utils.tasks;
|
||||
|
||||
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
|
||||
import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
|
||||
import speiger.src.collections.objects.utils.ObjectPriorityQueues;
|
||||
import speiger.src.coreengine.utils.counters.timers.CountdownSync;
|
||||
|
||||
public class MainThreadTaskProcessor
|
||||
{
|
||||
ObjectPriorityDequeue<ITask> tasks = ObjectPriorityQueues.synchronize(new ObjectArrayFIFOQueue<>());
|
||||
Watchdog watch;
|
||||
Thread watchThread;
|
||||
boolean running = false;
|
||||
long timeout;
|
||||
|
||||
public MainThreadTaskProcessor(long timeout, String name)
|
||||
{
|
||||
this.timeout = timeout;
|
||||
watch = new Watchdog(Thread.currentThread());
|
||||
watchThread = new Thread(watch, name+"-Thread-Watchdog");
|
||||
watchThread.start();
|
||||
}
|
||||
|
||||
public void setTimeout(long timeout)
|
||||
{
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public void addTask(ITask task)
|
||||
{
|
||||
tasks.enqueue(task);
|
||||
}
|
||||
|
||||
public void finishAllTasks()
|
||||
{
|
||||
if(tasks.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
running = true;
|
||||
while(!tasks.isEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
tasks.dequeue().execute();
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
running = false;
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
if(tasks.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
watch.unlock();
|
||||
running = true;
|
||||
boolean interrupted = false;
|
||||
while(!tasks.isEmpty() && !(interrupted |= Thread.interrupted()))
|
||||
{
|
||||
ITask task = tasks.dequeue();
|
||||
try
|
||||
{
|
||||
task.execute();
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{
|
||||
interrupted = true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(!task.isFinished())
|
||||
{
|
||||
tasks.enqueue(task);
|
||||
}
|
||||
}
|
||||
running = false;
|
||||
if(!interrupted)
|
||||
{
|
||||
watchThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void kill()
|
||||
{
|
||||
if(watchThread != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
watch.alive = false;
|
||||
watchThread.interrupt();
|
||||
watchThread = null;
|
||||
}
|
||||
|
||||
class Watchdog implements Runnable
|
||||
{
|
||||
Thread owner;
|
||||
boolean alive = true;
|
||||
CountdownSync timer = new CountdownSync();
|
||||
Object lock = new Object();
|
||||
|
||||
public Watchdog(Thread thread)
|
||||
{
|
||||
owner = thread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
while(alive)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized(lock)
|
||||
{
|
||||
lock.wait();
|
||||
}
|
||||
timer.sync(timeout);
|
||||
if(running)
|
||||
{
|
||||
owner.interrupt();
|
||||
}
|
||||
}
|
||||
catch(InterruptedException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
public void unlock()
|
||||
{
|
||||
synchronized(lock)
|
||||
{
|
||||
lock.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue