Add resource loading, scrollable container

Add Consumer interface
Add additional static Colors
This commit is contained in:
johni0702
2015-10-11 14:36:07 +02:00
parent 375f026a41
commit 475212449a
7 changed files with 707 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2015 johni0702
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.johni0702.minecraft.gui.container;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.OffsetGuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
import de.johni0702.minecraft.gui.element.GuiElement;
import de.johni0702.minecraft.gui.function.Scrollable;
import org.lwjgl.util.*;
public abstract class AbstractGuiScrollable<T extends AbstractGuiScrollable<T>> extends AbstractGuiContainer<T>
implements Scrollable {
private int offsetX, offsetY;
private final ReadablePoint negativeOffset = new ReadablePoint() {
@Override
public int getX() {
return -offsetX;
}
@Override
public int getY() {
return -offsetY;
}
@Override
public void getLocation(WritablePoint dest) {
dest.setLocation(getX(), getY());
}
};
private Direction scrollDirection = Direction.VERTICAL;
protected ReadableDimension lastRenderSize;
public AbstractGuiScrollable() {
}
public AbstractGuiScrollable(GuiContainer container) {
super(container);
}
@Override
public void convertFor(GuiElement element, Point point) {
super.convertFor(element, point);
if (point.getX() > 0 && point.getX() < lastRenderSize.getWidth()
&& point.getY() > 0 && point.getY() < lastRenderSize.getHeight()) {
point.translate(offsetX, offsetY);
} else {
point.setLocation(Integer.MIN_VALUE, Integer.MIN_VALUE);
}
}
@Override
public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) {
int width = size.getWidth();
int height = size.getHeight();
lastRenderSize = size;
size = super.calcMinSize();
size = new Dimension(Math.max(width, size.getWidth()), Math.max(height, size.getHeight()));
renderInfo = renderInfo.offsetMouse(-offsetX, -offsetY);
OffsetGuiRenderer offsetRenderer = new OffsetGuiRenderer(renderer, negativeOffset, size);
offsetRenderer.startUsing();
super.draw(offsetRenderer, size, renderInfo);
offsetRenderer.stopUsing();
}
@Override
public ReadableDimension calcMinSize() {
return new Dimension(0, 0);
}
@Override
public boolean scroll(ReadablePoint mousePosition, int dWheel) {
Point mouse = new Point(mousePosition);
if (getContainer() != null) {
getContainer().convertFor(this, mouse);
}
if (mouse.getX() > 0 && mouse.getY() > 0
&& mouse.getX() < lastRenderSize.getWidth() && mouse.getY() < lastRenderSize.getHeight()) {
// Reduce scrolling speed but make sure it is never rounded to 0
dWheel = (int) Math.copySign(Math.ceil(Math.abs(dWheel) / 4.0), dWheel);
if (scrollDirection == Direction.HORIZONTAL) {
scrollX(dWheel);
} else {
scrollY(dWheel);
}
return true;
}
return false;
}
public int getOffsetX() {
return offsetX;
}
public T setOffsetX(int offsetX) {
this.offsetX = offsetX;
return getThis();
}
public int getOffsetY() {
return offsetY;
}
public T setOffsetY(int offsetY) {
this.offsetY = offsetY;
return getThis();
}
public Direction getScrollDirection() {
return scrollDirection;
}
public T setScrollDirection(Direction scrollDirection) {
this.scrollDirection = scrollDirection;
return getThis();
}
public T scrollX(int dPixel) {
offsetX = Math.max(0, Math.min(super.calcMinSize().getWidth() - lastRenderSize.getWidth(), offsetX - dPixel));
return getThis();
}
public T scrollY(int dPixel) {
offsetY = Math.max(0, Math.min(super.calcMinSize().getHeight() - lastRenderSize.getHeight(), offsetY - dPixel));
return getThis();
}
public enum Direction {
VERTICAL, HORIZONTAL;
}
}

View File

@@ -0,0 +1,205 @@
/*
* Copyright (c) 2015 johni0702
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.johni0702.minecraft.gui.container;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
import de.johni0702.minecraft.gui.function.Draggable;
import de.johni0702.minecraft.gui.layout.CustomLayout;
import de.johni0702.minecraft.gui.layout.VerticalLayout;
import lombok.Getter;
import org.lwjgl.util.*;
import static de.johni0702.minecraft.gui.utils.Colors.TRANSPARENT;
import static org.lwjgl.util.ReadableColor.BLACK;
public abstract class AbstractGuiVerticalList<T extends AbstractGuiVerticalList<T>> extends AbstractGuiScrollable<T>
implements Draggable {
public static final ReadableColor BACKGROUND = new Color(0, 0, 0, 150);
@Getter
private final VerticalLayout listLayout = new VerticalLayout().setSpacing(3);
@Getter
private final GuiPanel listPanel = new GuiPanel(this).setLayout(listLayout);
{
setLayout(new CustomLayout<T>() {
@Override
protected void layout(T container, int width, int height) {
pos(listPanel, width / 2 - width(listPanel) / 2, 5);
}
@Override
public ReadableDimension calcMinSize(GuiContainer<?> container) {
final ReadableDimension panelSize = listPanel.getMinSize();
return new ReadableDimension() {
@Override
public int getWidth() {
return panelSize.getWidth();
}
@Override
public int getHeight() {
return panelSize.getHeight() + 10;
}
@Override
public void getSize(WritableDimension dest) {
dest.setSize(getWidth(), getHeight());
}
};
}
});
}
private boolean drawShadow, drawSlider;
private ReadablePoint lastMousePos;
private boolean draggingSlider;
public AbstractGuiVerticalList() {
}
public AbstractGuiVerticalList(GuiContainer container) {
super(container);
}
@Override
public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) {
int width = size.getWidth();
int height = size.getHeight();
if (drawShadow) {
renderer.drawRect(0, 0, width, height, BACKGROUND);
super.draw(renderer, size, renderInfo);
renderer.drawRect(0, 0, width, 4, BLACK, BLACK, TRANSPARENT, TRANSPARENT);
renderer.drawRect(0, height - 4, width, 4, TRANSPARENT, TRANSPARENT, BLACK, BLACK);
} else {
super.draw(renderer, size, renderInfo);
}
if (drawSlider) {
ReadableDimension contentSize = listPanel.calcMinSize();
int contentHeight = contentSize.getHeight() + 10;
if (contentHeight > height) {
int sliderX = width / 2 + contentSize.getWidth() / 2 + 3;
renderer.drawRect(sliderX, 0, 6, height, BLACK); // Draw slider background
int sliderY = getOffsetY() * height / contentHeight;
int sliderSize = height * height / contentHeight;
// Draw slider, with shadows
renderer.drawRect(sliderX, sliderY, 6, sliderSize, Color.LTGREY); // Slider
renderer.drawRect(sliderX + 5, sliderY, 1, sliderSize, Color.GREY); // Right shadow
renderer.drawRect(sliderX, sliderY + sliderSize - 1, 6, 1, Color.GREY); // Bottom shadow
}
}
}
@Override
public boolean mouseClick(ReadablePoint position, int button) {
position = convert(position);
if (isOnThis(position)) {
if (isOnSliderBar(position)) {
draggingSlider = true;
}
lastMousePos = position;
// We must not return true here
// because if we did, non of our children were able to process click events at all
}
return false;
}
@Override
public boolean mouseDrag(ReadablePoint position, int button, long timeSinceLastCall) {
position = convert(position);
if (lastMousePos != null) {
int dPixel = lastMousePos.getY() - position.getY();
if (draggingSlider) {
int contentHeight = listPanel.calcMinSize().getHeight();
int renderHeight = lastRenderSize.getHeight();
scrollY(dPixel * (contentHeight + renderHeight) / renderHeight);
} else {
scrollY(-dPixel);
}
lastMousePos = position;
// Returning false on purpose, see #mouseClick
}
return false;
}
@Override
public boolean mouseRelease(ReadablePoint position, int button) {
if (lastMousePos != null) {
lastMousePos = null;
draggingSlider = false;
// Returning false on purpose, see #mouseClick
}
return false;
}
private ReadablePoint convert(ReadablePoint readablePoint) {
if (getContainer() != null) {
Point point = new Point(readablePoint);
getContainer().convertFor(this, point);
return point;
}
return readablePoint;
}
private boolean isOnThis(ReadablePoint point) {
return point.getX() > 0 && point.getY() > 0
&& point.getX() < lastRenderSize.getWidth() && point.getY() < lastRenderSize.getHeight();
}
private boolean isOnSliderBar(ReadablePoint point) {
if (!drawSlider) {
return false;
}
int sliderX = lastRenderSize.getWidth() / 2 + listPanel.calcMinSize().getWidth() / 2 + 3;
return sliderX <= point.getX() && point.getX() < sliderX + 6;
}
private boolean isOnBackground(ReadablePoint point) {
int width = lastRenderSize.getWidth();
int listPanelWidth = listPanel.calcMinSize().getWidth();
return point.getX() < width / 2 - listPanelWidth / 2
|| width / 2 + listPanelWidth / 2 + (drawSlider ? 6 : 0) < point.getX();
}
public boolean doesDrawSlider() {
return drawSlider;
}
public T setDrawSlider(boolean drawSlider) {
this.drawSlider = drawSlider;
return getThis();
}
public boolean doesDrawShadow() {
return drawShadow;
}
public T setDrawShadow(boolean drawShadow) {
this.drawShadow = drawShadow;
return getThis();
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2015 johni0702
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.johni0702.minecraft.gui.container;
public class GuiScrollable extends AbstractGuiScrollable<GuiScrollable> {
@Override
protected GuiScrollable getThis() {
return this;
}
}

View File

@@ -0,0 +1,217 @@
/*
* Copyright (c) 2015 johni0702
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.johni0702.minecraft.gui.element.advanced;
import com.google.common.base.Supplier;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
import de.johni0702.minecraft.gui.container.AbstractGuiVerticalList;
import de.johni0702.minecraft.gui.container.GuiContainer;
import de.johni0702.minecraft.gui.container.GuiPanel;
import de.johni0702.minecraft.gui.element.GuiElement;
import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.function.Clickable;
import de.johni0702.minecraft.gui.function.Closeable;
import de.johni0702.minecraft.gui.function.Loadable;
import de.johni0702.minecraft.gui.function.Tickable;
import de.johni0702.minecraft.gui.layout.CustomLayout;
import de.johni0702.minecraft.gui.layout.VerticalLayout;
import de.johni0702.minecraft.gui.utils.Colors;
import de.johni0702.minecraft.gui.utils.Consumer;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.Point;
import org.lwjgl.util.ReadableDimension;
import org.lwjgl.util.ReadablePoint;
import java.util.ArrayList;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
public abstract class AbstractGuiResourceLoadingList
<T extends AbstractGuiResourceLoadingList<T, U>, U extends GuiElement<U> & Comparable<U>>
extends AbstractGuiVerticalList<T> implements Tickable, Loadable, Closeable {
private static final String[] LOADING_TEXT = {"Ooo", "oOo", "ooO", "oOo"};
private final GuiLabel loadingElement = new GuiLabel();
private final GuiPanel resourcesPanel = new GuiPanel(getListPanel()).setLayout(new VerticalLayout());
private Consumer<Consumer<Supplier<U>>> onLoad;
private Runnable onSelectionChanged;
private Thread loaderThread;
private Queue<Runnable> resourcesQueue = new ConcurrentLinkedQueue<>();
private int tick;
private Element selected;
public AbstractGuiResourceLoadingList() {
}
public AbstractGuiResourceLoadingList(GuiContainer container) {
super(container);
}
@Override
public void tick() {
loadingElement.setText(LOADING_TEXT[tick++ / 5 % LOADING_TEXT.length]);
Runnable resource;
while ((resource = resourcesQueue.poll()) != null) {
resource.run();
}
}
@Override
public void load() {
// Stop current loading
if (loaderThread != null) {
loaderThread.interrupt();
try {
loaderThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
// Clear list
resourcesQueue.clear();
for (GuiElement element : new ArrayList<>(resourcesPanel.getChildren())) {
resourcesPanel.removeElement(element);
}
selected = null;
onSelectionChanged();
// Load new data
loaderThread = new Thread(new Runnable() {
@Override
public void run() {
getListPanel().addElements(new VerticalLayout.Data(0.5), loadingElement);
try {
onLoad.consume(new Consumer<Supplier<U>>() {
@Override
public void consume(final Supplier<U> obj) {
resourcesQueue.offer(new Runnable() {
@Override
public void run() {
resourcesPanel.addElements(null, new Element(obj.get()));
}
});
}
});
} finally {
resourcesQueue.offer(new Runnable() {
@Override
public void run() {
getListPanel().removeElement(loadingElement);
}
});
}
}
});
getListPanel().addElements(new VerticalLayout.Data(0.5), loadingElement);
loaderThread.start();
}
@Override
public void close() {
loaderThread.interrupt();
}
public T onLoad(Consumer<Consumer<Supplier<U>>> function) {
this.onLoad = function;
return getThis();
}
public void onSelectionChanged() {
if (onSelectionChanged != null) {
onSelectionChanged.run();
}
}
public T onSelectionChanged(Runnable onSelectionChanged) {
this.onSelectionChanged = onSelectionChanged;
return getThis();
}
public U getSelected() {
return selected == null ? null : selected.resource;
}
private class Element extends GuiPanel implements Clickable, Comparable<Element> {
private final U resource;
private ReadableDimension size;
public Element(final U resource) {
this.resource = resource;
addElements(null, resource);
setLayout(new CustomLayout<GuiPanel>() {
@Override
protected void layout(GuiPanel container, int width, int height) {
pos(resource, 2, 2);
}
@Override
public ReadableDimension calcMinSize(GuiContainer<?> container) {
ReadableDimension size = resource.getMinSize();
return new Dimension(size.getWidth() + 4, size.getHeight() + 4);
}
});
}
@Override
public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) {
this.size = size;
if (selected == this) {
// Draw selection
int w = size.getWidth();
int h = size.getHeight();
// Black background
renderer.drawRect(0, 0, w, h, Colors.BLACK);
// Light gray border
renderer.drawRect(0, 0, w, 1, Colors.LIGHT_GRAY); // Top
renderer.drawRect(0, h - 1, w, 1, Colors.LIGHT_GRAY); // Bottom
renderer.drawRect(0, 0, 1, h, Colors.LIGHT_GRAY); // Left
renderer.drawRect(w - 1, 0, 1, h, Colors.LIGHT_GRAY); // Right
}
super.draw(renderer, size, renderInfo);
}
@Override
public boolean mouseClick(ReadablePoint position, int button) {
Point point = new Point(position);
getContainer().convertFor(this, point);
if (point.getX() > 0 && point.getX() < size.getWidth()
&& point.getY() > 0 && point.getY() < size.getHeight()) {
if (selected != this) {
selected = this;
onSelectionChanged();
}
return true;
}
return false;
}
@Override
public int compareTo(Element o) {
return resource.compareTo(o.resource);
}
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2015 johni0702
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.johni0702.minecraft.gui.element.advanced;
import de.johni0702.minecraft.gui.container.GuiContainer;
import de.johni0702.minecraft.gui.element.GuiElement;
public class GuiResourceLoadingList<U extends GuiElement<U> & Comparable<U>>
extends AbstractGuiResourceLoadingList<GuiResourceLoadingList<U>, U> {
public GuiResourceLoadingList() {
}
public GuiResourceLoadingList(GuiContainer container) {
super(container);
}
@Override
protected GuiResourceLoadingList<U> getThis() {
return this;
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2015 johni0702
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.johni0702.minecraft.gui.utils;
import org.lwjgl.util.Color;
import org.lwjgl.util.ReadableColor;
public interface Colors extends ReadableColor {
ReadableColor TRANSPARENT = new Color(0, 0, 0, 0);
ReadableColor HALF_TRANSPARENT = new Color(0, 0, 0, 128);
ReadableColor LIGHT_GRAY = new Color(192, 192, 192);
ReadableColor DARK_RED = new Color(170, 0, 0);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2015 johni0702
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.johni0702.minecraft.gui.utils;
public interface Consumer<T> {
void consume(T obj);
}