From a6f9e06c83dbcbe77fc10f2c2a610af562fdab40 Mon Sep 17 00:00:00 2001 From: johni0702 Date: Mon, 13 Jul 2015 09:57:49 +0200 Subject: [PATCH] Add GuiDropdownMenu --- .../advanced/AbstractGuiDropdownMenu.java | 226 ++++++++++++++++++ .../gui/element/advanced/GuiDropdownMenu.java | 40 ++++ .../element/advanced/IGuiDropdownMenu.java | 43 ++++ 3 files changed, 309 insertions(+) create mode 100644 src/main/java/de/johni0702/minecraft/gui/element/advanced/AbstractGuiDropdownMenu.java create mode 100644 src/main/java/de/johni0702/minecraft/gui/element/advanced/GuiDropdownMenu.java create mode 100644 src/main/java/de/johni0702/minecraft/gui/element/advanced/IGuiDropdownMenu.java diff --git a/src/main/java/de/johni0702/minecraft/gui/element/advanced/AbstractGuiDropdownMenu.java b/src/main/java/de/johni0702/minecraft/gui/element/advanced/AbstractGuiDropdownMenu.java new file mode 100644 index 00000000..6b8ea487 --- /dev/null +++ b/src/main/java/de/johni0702/minecraft/gui/element/advanced/AbstractGuiDropdownMenu.java @@ -0,0 +1,226 @@ +/* + * 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.GuiRenderer; +import de.johni0702.minecraft.gui.OffsetGuiRenderer; +import de.johni0702.minecraft.gui.RenderInfo; +import de.johni0702.minecraft.gui.container.GuiContainer; +import de.johni0702.minecraft.gui.container.GuiPanel; +import de.johni0702.minecraft.gui.element.AbstractComposedGuiElement; +import de.johni0702.minecraft.gui.element.AbstractGuiClickable; +import de.johni0702.minecraft.gui.element.GuiElement; +import de.johni0702.minecraft.gui.function.Clickable; +import de.johni0702.minecraft.gui.layout.VerticalLayout; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import net.minecraft.client.gui.FontRenderer; +import org.lwjgl.util.*; + +import java.util.Collection; +import java.util.Collections; + +public abstract class AbstractGuiDropdownMenu> + extends AbstractComposedGuiElement implements IGuiDropdownMenu, Clickable { + private static final ReadableColor OUTLINE_COLOR = new Color(160, 160, 160); + + @Getter + private int selected; + + @Getter + private V[] values; + + @Getter + private boolean opened; + + private GuiPanel dropdown; + + private ReadableDimension size; + + public AbstractGuiDropdownMenu() { + } + + public AbstractGuiDropdownMenu(GuiContainer container) { + super(container); + } + + @Override + public int getMaxLayer() { + return opened ? 1 : 0; + } + + @Override + protected ReadableDimension calcMinSize() { + FontRenderer fontRenderer = getMinecraft().fontRendererObj; + int maxWidth = 0; + for (V value : values) { + int width = fontRenderer.getStringWidth(value.toString()); + if (width > maxWidth) { + maxWidth = width; + } + } + return new Dimension(11 + maxWidth + fontRenderer.FONT_HEIGHT, fontRenderer.FONT_HEIGHT + 4); + } + + @Override + public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) { + FontRenderer fontRenderer = getMinecraft().fontRendererObj; + if (renderInfo.layer == 0) { + this.size = size; + int width = size.getWidth(); + int height = size.getHeight(); + + // Draw box + renderer.drawRect(0, 0, width, height, OUTLINE_COLOR); + renderer.drawRect(1, 1, width - 2, height - 2, ReadableColor.BLACK); + renderer.drawRect(width - height, 0, 1, height, OUTLINE_COLOR); + + // Draw triangle + int base = height - 6; + int tHeight = base / 2; + int x = width - 3 - base / 2; + int y = height / 2 - 2; + for (int layer = tHeight; layer > 0; layer--) { + renderer.drawRect(x - layer, y + (tHeight - layer), layer * 2 - 1, 1, OUTLINE_COLOR); + } + + renderer.drawString(3, height / 2 - fontRenderer.FONT_HEIGHT / 2, ReadableColor.WHITE, getSelectedValue().toString()); + } else if (renderInfo.layer == 1) { + ReadablePoint offsetPoint = new Point(0, size.getHeight()); + ReadableDimension offsetSize = new Dimension(size.getWidth(), (fontRenderer.FONT_HEIGHT + 5) * values.length); + OffsetGuiRenderer offsetRenderer = new OffsetGuiRenderer(renderer, offsetPoint, offsetSize); + dropdown.draw(offsetRenderer, offsetSize, renderInfo.offsetMouse(0, offsetPoint.getY()).layer(0)); + } + } + + @Override + public T setValues(V... values) { + this.values = values; + dropdown = new GuiPanel(){ + @Override + public void convertFor(GuiElement element, Point point) { + super.convertFor(element, point); + point.translate(0, -size.getHeight()); + AbstractGuiDropdownMenu parent = AbstractGuiDropdownMenu.this; + if (parent.getContainer() != null) { + parent.getContainer().convertFor(parent, point); + } + } + }.setLayout(new VerticalLayout()); + for (V value : values) { + dropdown.addElements(null, new DropdownEntry(value)); + } + return getThis(); + } + + @Override + public T setSelected(int selected) { + this.selected = selected; + return getThis(); + } + + @Override + public T setSelected(V value) { + for (int i = 0; i < values.length; i++) { + if (values[i].equals(value)) { + return setSelected(i); + } + } + throw new IllegalArgumentException("The value " + value + " is not in this dropdown menu."); + } + + @Override + public V getSelectedValue() { + return values[selected]; + } + + @Override + public T setOpened(boolean opened) { + this.opened = opened; + return getThis(); + } + + @Override + public Collection getChildren() { + return opened ? Collections.singletonList(dropdown) : Collections.emptyList(); + } + + @Override + public boolean mouseClick(ReadablePoint position, int button) { + Point pos = new Point(position); + if (getContainer() != null) { + getContainer().convertFor(this, pos); + } + + if (isEnabled()) { + if (isMouseHovering(pos)) { + setOpened(!isOpened()); + return true; + } + } + return false; + } + + protected boolean isMouseHovering(ReadablePoint pos) { + return pos.getX() > 0 && pos.getY() > 0 + && pos.getX() < size.getWidth() && pos.getY() < size.getHeight(); + } + + @RequiredArgsConstructor + private class DropdownEntry extends AbstractGuiClickable { + private final V value; + + @Override + protected DropdownEntry getThis() { + return this; + } + + @Override + protected ReadableDimension calcMinSize() { + return new Dimension(0, getMinecraft().fontRendererObj.FONT_HEIGHT + 5); + } + + @Override + public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) { + super.draw(renderer, size, renderInfo); + int width = size.getWidth(); + int height = size.getHeight(); + + renderer.drawRect(0, 0, width, height, OUTLINE_COLOR); + renderer.drawRect(1, 0, width - 2, height - 1, ReadableColor.BLACK); + renderer.drawString(3, 2, ReadableColor.WHITE, value.toString()); + } + + @Override + public boolean mouseClick(ReadablePoint position, int button) { + boolean result = super.mouseClick(position, button); + setOpened(false); + return result; + } + + @Override + protected void onClick() { + setSelected(value); + } + } +} diff --git a/src/main/java/de/johni0702/minecraft/gui/element/advanced/GuiDropdownMenu.java b/src/main/java/de/johni0702/minecraft/gui/element/advanced/GuiDropdownMenu.java new file mode 100644 index 00000000..db28b632 --- /dev/null +++ b/src/main/java/de/johni0702/minecraft/gui/element/advanced/GuiDropdownMenu.java @@ -0,0 +1,40 @@ +/* + * 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; + +public class GuiDropdownMenu extends AbstractGuiDropdownMenu> { + + public GuiDropdownMenu() { + } + + public GuiDropdownMenu(GuiContainer container) { + super(container); + } + + @Override + protected GuiDropdownMenu getThis() { + return this; + } +} diff --git a/src/main/java/de/johni0702/minecraft/gui/element/advanced/IGuiDropdownMenu.java b/src/main/java/de/johni0702/minecraft/gui/element/advanced/IGuiDropdownMenu.java new file mode 100644 index 00000000..bacd98b3 --- /dev/null +++ b/src/main/java/de/johni0702/minecraft/gui/element/advanced/IGuiDropdownMenu.java @@ -0,0 +1,43 @@ +/* + * 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.element.GuiElement; + +public interface IGuiDropdownMenu> extends GuiElement { + T setValues(V... values); + + T setSelected(int selected); + + T setSelected(V value); + + V getSelectedValue(); + + T setOpened(boolean opened); + + int getSelected(); + + V[] getValues(); + + boolean isOpened(); +}