├── LICENSE.txt ├── README.md └── src └── org └── darkstorm └── minecraft └── gui ├── AbstractGuiManager.java ├── ExampleGuiManager.java ├── GuiManager.java ├── component ├── AbstractComponent.java ├── AbstractContainer.java ├── BoundedRangeComponent.java ├── Button.java ├── ButtonGroup.java ├── CheckButton.java ├── ComboBox.java ├── Component.java ├── Container.java ├── DraggableComponent.java ├── Frame.java ├── Label.java ├── Panel.java ├── ProgressBar.java ├── RadioButton.java ├── SelectableComponent.java ├── Slider.java ├── TextComponent.java └── basic │ ├── BasicButton.java │ ├── BasicButtonGroup.java │ ├── BasicCheckButton.java │ ├── BasicComboBox.java │ ├── BasicFrame.java │ ├── BasicLabel.java │ ├── BasicPanel.java │ ├── BasicProgressBar.java │ ├── BasicRadioButton.java │ └── BasicSlider.java ├── font └── UnicodeFontRenderer.java ├── layout ├── BasicLayoutManager.java ├── Constraint.java ├── GridLayoutManager.java └── LayoutManager.java ├── listener ├── ButtonListener.java ├── ComboBoxListener.java ├── ComponentListener.java ├── SelectableComponentListener.java └── SliderListener.java ├── theme ├── AbstractComponentUI.java ├── AbstractTheme.java ├── ComponentUI.java ├── Theme.java └── simple │ ├── SimpleButtonUI.java │ ├── SimpleCheckButtonUI.java │ ├── SimpleComboBoxUI.java │ ├── SimpleFrameUI.java │ ├── SimpleLabelUI.java │ ├── SimplePanelUI.java │ ├── SimpleProgressBarUI.java │ ├── SimpleSliderUI.java │ └── SimpleTheme.java └── util ├── GuiManagerDisplayScreen.java └── RenderUtil.java /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, DarkStorm (darkstorm@evilminecraft.net) 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Minecraft GUI API 2 | ================= 3 | 4 | Provides a toolkit for creating widgets through Minecraft. Users can 5 | create frames and various controls, as well as provide customized 6 | layout managers and themes. Themes have complete control over the 7 | rendering process by providing "UIs" for specific component types that 8 | handle rendering components of their respective type. 9 | 10 | Libraries 11 | --------- 12 | 13 | The only library currently required by the project is Slick2D, which can 14 | be found at [http://slick.ninjacave.com/]. The dependency upon this library may 15 | be removed by deletion of UnicodeFontRenderer.java and slight modification 16 | to SimpleTheme.java to replace the instantiation of UnicodeFontRenderer 17 | with the instantiation of a normal FontRenderer. 18 | 19 | [http://slick.ninjacave.com/]: http://slick.ninjacave.com/ -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/AbstractGuiManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, DarkStorm (darkstorm@evilminecraft.net) 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | package org.darkstorm.minecraft.gui; 26 | 27 | import java.util.List; 28 | import java.util.concurrent.CopyOnWriteArrayList; 29 | 30 | import org.darkstorm.minecraft.gui.component.Frame; 31 | import org.darkstorm.minecraft.gui.theme.Theme; 32 | 33 | /** 34 | * Minecraft GUI API 35 | * 36 | * @author DarkStorm (darkstorm@evilminecraft.net) 37 | */ 38 | public abstract class AbstractGuiManager implements GuiManager { 39 | private final List frames; 40 | 41 | private Theme theme; 42 | 43 | public AbstractGuiManager() { 44 | frames = new CopyOnWriteArrayList(); 45 | } 46 | 47 | @Override 48 | public abstract void setup(); 49 | 50 | @Override 51 | public void addFrame(Frame frame) { 52 | frame.setTheme(theme); 53 | frames.add(0, frame); 54 | } 55 | 56 | @Override 57 | public void removeFrame(Frame frame) { 58 | frames.remove(frame); 59 | } 60 | 61 | @Override 62 | public Frame[] getFrames() { 63 | return frames.toArray(new Frame[frames.size()]); 64 | } 65 | 66 | @Override 67 | public void bringForward(Frame frame) { 68 | if(frames.remove(frame)) 69 | frames.add(0, frame); 70 | } 71 | 72 | @Override 73 | public Theme getTheme() { 74 | return theme; 75 | } 76 | 77 | @Override 78 | public void setTheme(Theme theme) { 79 | this.theme = theme; 80 | for(Frame frame : frames) 81 | frame.setTheme(theme); 82 | resizeComponents(); 83 | } 84 | 85 | protected abstract void resizeComponents(); 86 | 87 | @Override 88 | public void render() { 89 | Frame[] frames = getFrames(); 90 | for(int i = frames.length - 1; i >= 0; i--) 91 | frames[i].render(); 92 | } 93 | 94 | @Override 95 | public void renderPinned() { 96 | Frame[] frames = getFrames(); 97 | for(int i = frames.length - 1; i >= 0; i--) 98 | if(frames[i].isPinned()) 99 | frames[i].render(); 100 | } 101 | 102 | @Override 103 | public void update() { 104 | Frame[] frames = getFrames(); 105 | for(int i = frames.length - 1; i >= 0; i--) 106 | frames[i].update(); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/ExampleGuiManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, DarkStorm (darkstorm@evilminecraft.net) 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | package org.darkstorm.minecraft.gui; 26 | 27 | import java.awt.*; 28 | import java.util.concurrent.atomic.AtomicBoolean; 29 | 30 | import net.minecraft.client.Minecraft; 31 | 32 | import org.darkstorm.minecraft.gui.component.BoundedRangeComponent.ValueDisplay; 33 | import org.darkstorm.minecraft.gui.component.*; 34 | import org.darkstorm.minecraft.gui.component.Button; 35 | import org.darkstorm.minecraft.gui.component.Component; 36 | import org.darkstorm.minecraft.gui.component.Frame; 37 | import org.darkstorm.minecraft.gui.component.basic.*; 38 | import org.darkstorm.minecraft.gui.listener.*; 39 | import org.darkstorm.minecraft.gui.theme.Theme; 40 | import org.darkstorm.minecraft.gui.theme.simple.SimpleTheme; 41 | 42 | /** 43 | * Minecraft GUI API 44 | * 45 | * This class is not actually intended for use; rather, you should use this as a 46 | * template for your actual GuiManager, as the creation of frames is highly 47 | * implementation-specific. 48 | * 49 | * @author DarkStorm (darkstorm@evilminecraft.net) 50 | */ 51 | public final class ExampleGuiManager extends AbstractGuiManager { 52 | private class ModuleFrame extends BasicFrame { 53 | private ModuleFrame() { 54 | } 55 | 56 | private ModuleFrame(String title) { 57 | super(title); 58 | } 59 | } 60 | 61 | private final AtomicBoolean setup; 62 | 63 | public ExampleGuiManager() { 64 | setup = new AtomicBoolean(); 65 | } 66 | 67 | @Override 68 | public void setup() { 69 | if(!setup.compareAndSet(false, true)) 70 | return; 71 | 72 | createTestFrame(); 73 | 74 | /* Sample module frame setup 75 | 76 | final Map categoryFrames = new HashMap(); 77 | for(Module module : ClientNameHere.getClientInstance().getModuleManager().getModules()) { 78 | if(!module.isToggleable()) 79 | continue; 80 | ModuleFrame frame = categoryFrames.get(module.getCategory()); 81 | if(frame == null) { 82 | String name = module.getCategory().name().toLowerCase(); 83 | name = Character.toUpperCase(name.charAt(0)) 84 | + name.substring(1); 85 | frame = new ModuleFrame(name); 86 | frame.setTheme(theme); 87 | frame.setLayoutManager(new GridLayoutManager(2, 0)); 88 | frame.setVisible(true); 89 | frame.setClosable(false); 90 | frame.setMinimized(true); 91 | addFrame(frame); 92 | categoryFrames.put(module.getCategory(), frame); 93 | } 94 | frame.add(new BasicLabel(module.getName())); 95 | final Module updateModule = module; 96 | Button button = new BasicButton(module.isEnabled() ? "Disable" 97 | : "Enable") { 98 | @Override 99 | public void update() { 100 | setText(updateModule.isEnabled() ? "Disable" : "Enable"); 101 | } 102 | }; 103 | button.addButtonListener(new ButtonListener() { 104 | @Override 105 | public void onButtonPress(Button button) { 106 | updateModule.toggle(); 107 | button.setText(updateModule.isEnabled() ? "Disable" 108 | : "Enable"); 109 | } 110 | }); 111 | frame.add(button, HorizontalGridConstraint.RIGHT); 112 | } 113 | */ 114 | 115 | // Optional equal sizing and auto-positioning 116 | resizeComponents(); 117 | Minecraft minecraft = Minecraft.getMinecraft(); 118 | Dimension maxSize = recalculateSizes(); 119 | int offsetX = 5, offsetY = 5; 120 | int scale = minecraft.gameSettings.guiScale; 121 | if(scale == 0) 122 | scale = 1000; 123 | int scaleFactor = 0; 124 | while(scaleFactor < scale && minecraft.displayWidth / (scaleFactor + 1) >= 320 && minecraft.displayHeight / (scaleFactor + 1) >= 240) 125 | scaleFactor++; 126 | for(Frame frame : getFrames()) { 127 | frame.setX(offsetX); 128 | frame.setY(offsetY); 129 | offsetX += maxSize.width + 5; 130 | if(offsetX + maxSize.width + 5 > minecraft.displayWidth / scaleFactor) { 131 | offsetX = 5; 132 | offsetY += maxSize.height + 5; 133 | } 134 | } 135 | } 136 | 137 | private void createTestFrame() { 138 | Theme theme = getTheme(); 139 | Frame testFrame = new BasicFrame("Frame"); 140 | testFrame.setTheme(theme); 141 | 142 | testFrame.add(new BasicLabel("TEST LOL")); 143 | testFrame.add(new BasicLabel("TEST 23423")); 144 | testFrame.add(new BasicLabel("TE123123123ST LOL")); 145 | testFrame.add(new BasicLabel("31243 LO3242L432")); 146 | BasicButton testButton = new BasicButton("Duplicate this frame!"); 147 | testButton.addButtonListener(new ButtonListener() { 148 | 149 | @Override 150 | public void onButtonPress(Button button) { 151 | createTestFrame(); 152 | } 153 | }); 154 | testFrame.add(new BasicCheckButton("This is a checkbox")); 155 | testFrame.add(testButton); 156 | ComboBox comboBox = new BasicComboBox("Simple theme", "Other theme", "Other theme 2"); 157 | comboBox.addComboBoxListener(new ComboBoxListener() { 158 | 159 | @Override 160 | public void onComboBoxSelectionChanged(ComboBox comboBox) { 161 | Theme theme; 162 | switch(comboBox.getSelectedIndex()) { 163 | case 0: 164 | theme = new SimpleTheme(); 165 | break; 166 | case 1: 167 | // Some other theme 168 | // break; 169 | case 2: 170 | // Another theme 171 | // break; 172 | default: 173 | return; 174 | } 175 | setTheme(theme); 176 | } 177 | }); 178 | testFrame.add(comboBox); 179 | Slider slider = new BasicSlider("Test"); 180 | slider.setContentSuffix("things"); 181 | slider.setValueDisplay(ValueDisplay.INTEGER); 182 | testFrame.add(slider); 183 | testFrame.add(new BasicProgressBar(50, 0, 100, 1, ValueDisplay.PERCENTAGE)); 184 | 185 | testFrame.setX(50); 186 | testFrame.setY(50); 187 | Dimension defaultDimension = theme.getUIForComponent(testFrame).getDefaultSize(testFrame); 188 | testFrame.setWidth(defaultDimension.width); 189 | testFrame.setHeight(defaultDimension.height); 190 | testFrame.layoutChildren(); 191 | testFrame.setVisible(true); 192 | testFrame.setMinimized(true); 193 | addFrame(testFrame); 194 | } 195 | 196 | @Override 197 | protected void resizeComponents() { 198 | Theme theme = getTheme(); 199 | Frame[] frames = getFrames(); 200 | Button enable = new BasicButton("Enable"); 201 | Button disable = new BasicButton("Disable"); 202 | Dimension enableSize = theme.getUIForComponent(enable).getDefaultSize(enable); 203 | Dimension disableSize = theme.getUIForComponent(disable).getDefaultSize(disable); 204 | int buttonWidth = Math.max(enableSize.width, disableSize.width); 205 | int buttonHeight = Math.max(enableSize.height, disableSize.height); 206 | for(Frame frame : frames) { 207 | if(frame instanceof ModuleFrame) { 208 | for(Component component : frame.getChildren()) { 209 | if(component instanceof Button) { 210 | component.setWidth(buttonWidth); 211 | component.setHeight(buttonHeight); 212 | } 213 | } 214 | } 215 | } 216 | recalculateSizes(); 217 | } 218 | 219 | private Dimension recalculateSizes() { 220 | Frame[] frames = getFrames(); 221 | int maxWidth = 0, maxHeight = 0; 222 | for(Frame frame : frames) { 223 | Dimension defaultDimension = frame.getTheme().getUIForComponent(frame).getDefaultSize(frame); 224 | maxWidth = Math.max(maxWidth, defaultDimension.width); 225 | frame.setHeight(defaultDimension.height); 226 | if(frame.isMinimized()) { 227 | for(Rectangle area : frame.getTheme().getUIForComponent(frame).getInteractableRegions(frame)) 228 | maxHeight = Math.max(maxHeight, area.height); 229 | } else 230 | maxHeight = Math.max(maxHeight, defaultDimension.height); 231 | } 232 | for(Frame frame : frames) { 233 | frame.setWidth(maxWidth); 234 | frame.layoutChildren(); 235 | } 236 | return new Dimension(maxWidth, maxHeight); 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/GuiManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, DarkStorm (darkstorm@evilminecraft.net) 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | package org.darkstorm.minecraft.gui; 26 | 27 | import org.darkstorm.minecraft.gui.component.Frame; 28 | import org.darkstorm.minecraft.gui.theme.Theme; 29 | 30 | /** 31 | * Minecraft GUI API 32 | * 33 | * @author DarkStorm (darkstorm@evilminecraft.net) 34 | */ 35 | public interface GuiManager { 36 | public void setup(); 37 | 38 | public void addFrame(Frame frame); 39 | 40 | public void removeFrame(Frame frame); 41 | 42 | public Frame[] getFrames(); 43 | 44 | public void bringForward(Frame frame); 45 | 46 | public Theme getTheme(); 47 | 48 | public void setTheme(Theme theme); 49 | 50 | public void render(); 51 | 52 | public void renderPinned(); 53 | 54 | public void update(); 55 | } 56 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/AbstractComponent.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | import java.awt.*; 4 | import java.util.List; 5 | import java.util.concurrent.CopyOnWriteArrayList; 6 | 7 | import org.darkstorm.minecraft.gui.listener.ComponentListener; 8 | import org.darkstorm.minecraft.gui.theme.*; 9 | 10 | public abstract class AbstractComponent implements Component { 11 | private Container parent = null; 12 | private Theme theme; 13 | 14 | protected Rectangle area = new Rectangle(0, 0, 0, 0); 15 | protected ComponentUI ui; 16 | protected Color foreground, background; 17 | protected boolean enabled = true, visible = true; 18 | 19 | private List listeners = new CopyOnWriteArrayList(); 20 | 21 | public void render() { 22 | if(ui == null) 23 | return; 24 | ui.render(this); 25 | } 26 | 27 | @Override 28 | public void update() { 29 | if(ui == null) 30 | return; 31 | ui.handleUpdate(this); 32 | } 33 | 34 | protected ComponentUI getUI() { 35 | return theme.getUIForComponent(this); 36 | } 37 | 38 | @Override 39 | public void onMousePress(int x, int y, int button) { 40 | if(ui != null) { 41 | for(Rectangle area : ui.getInteractableRegions(this)) { 42 | if(area.contains(x, y)) { 43 | ui.handleInteraction(this, new Point(x, y), button); 44 | break; 45 | } 46 | } 47 | } 48 | } 49 | 50 | @Override 51 | public void onMouseRelease(int x, int y, int button) { 52 | } 53 | 54 | public Theme getTheme() { 55 | return theme; 56 | } 57 | 58 | public void setTheme(Theme theme) { 59 | Theme oldTheme = this.theme; 60 | this.theme = theme; 61 | if(theme == null) { 62 | ui = null; 63 | foreground = null; 64 | background = null; 65 | return; 66 | } 67 | 68 | ui = getUI(); 69 | boolean changeArea; 70 | if(oldTheme != null) { 71 | Dimension defaultSize = oldTheme.getUIForComponent(this).getDefaultSize(this); 72 | changeArea = area.width == defaultSize.width && area.height == defaultSize.height; 73 | } else 74 | changeArea = area.equals(new Rectangle(0, 0, 0, 0)); 75 | if(changeArea) { 76 | Dimension defaultSize = ui.getDefaultSize(this); 77 | area = new Rectangle(area.x, area.y, defaultSize.width, defaultSize.height); 78 | } 79 | foreground = ui.getDefaultForegroundColor(this); 80 | background = ui.getDefaultBackgroundColor(this); 81 | } 82 | 83 | public int getX() { 84 | return area.x; 85 | } 86 | 87 | public int getY() { 88 | return area.y; 89 | } 90 | 91 | public int getWidth() { 92 | return area.width; 93 | } 94 | 95 | public int getHeight() { 96 | return area.height; 97 | } 98 | 99 | public void setX(int x) { 100 | area.x = x; 101 | } 102 | 103 | public void setY(int y) { 104 | area.y = y; 105 | } 106 | 107 | public void setWidth(int width) { 108 | area.width = width; 109 | } 110 | 111 | public void setHeight(int height) { 112 | area.height = height; 113 | } 114 | 115 | @Override 116 | public Color getBackgroundColor() { 117 | return background; 118 | } 119 | 120 | @Override 121 | public Color getForegroundColor() { 122 | return foreground; 123 | } 124 | 125 | @Override 126 | public void setBackgroundColor(Color color) { 127 | background = color; 128 | } 129 | 130 | @Override 131 | public void setForegroundColor(Color color) { 132 | foreground = color; 133 | } 134 | 135 | public Point getLocation() { 136 | return area.getLocation(); 137 | } 138 | 139 | public Dimension getSize() { 140 | return area.getSize(); 141 | } 142 | 143 | public Rectangle getArea() { 144 | return area; 145 | } 146 | 147 | public Container getParent() { 148 | return parent; 149 | } 150 | 151 | public void setParent(Container parent) { 152 | if(!parent.hasChild(this) || (this.parent != null && this.parent.hasChild(this))) 153 | throw new IllegalArgumentException(); 154 | this.parent = parent; 155 | } 156 | 157 | public void resize() { 158 | Dimension defaultDimension = ui.getDefaultSize(this); 159 | setWidth(defaultDimension.width); 160 | setHeight(defaultDimension.height); 161 | } 162 | 163 | public boolean isEnabled() { 164 | return enabled; 165 | } 166 | 167 | public void setEnabled(boolean enabled) { 168 | if(parent != null && !parent.isEnabled()) 169 | this.enabled = false; 170 | else 171 | this.enabled = enabled; 172 | } 173 | 174 | public boolean isVisible() { 175 | return visible; 176 | } 177 | 178 | public void setVisible(boolean visible) { 179 | if(parent != null && !parent.isVisible()) 180 | this.visible = false; 181 | else 182 | this.visible = visible; 183 | } 184 | 185 | protected void addListener(ComponentListener listener) { 186 | synchronized(listeners) { 187 | listeners.add(listener); 188 | } 189 | } 190 | 191 | protected void removeListener(ComponentListener listener) { 192 | synchronized(listeners) { 193 | listeners.remove(listener); 194 | } 195 | } 196 | 197 | protected ComponentListener[] getListeners() { 198 | synchronized(listeners) { 199 | return listeners.toArray(new ComponentListener[listeners.size()]); 200 | } 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/AbstractContainer.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | import java.util.*; 4 | 5 | import java.awt.Rectangle; 6 | 7 | import org.darkstorm.minecraft.gui.layout.*; 8 | import org.darkstorm.minecraft.gui.theme.Theme; 9 | 10 | public abstract class AbstractContainer extends AbstractComponent implements 11 | Container { 12 | private final Map children = new LinkedHashMap(); 13 | 14 | private LayoutManager layoutManager = new BasicLayoutManager(); 15 | 16 | @Override 17 | public void render() { 18 | super.render(); 19 | 20 | synchronized(children) { 21 | for(Component child : children.keySet()) 22 | child.render(); 23 | } 24 | } 25 | 26 | public LayoutManager getLayoutManager() { 27 | return layoutManager; 28 | } 29 | 30 | public void setLayoutManager(LayoutManager layoutManager) { 31 | if(layoutManager == null) 32 | layoutManager = new BasicLayoutManager(); 33 | this.layoutManager = layoutManager; 34 | 35 | layoutChildren(); 36 | } 37 | 38 | public Component[] getChildren() { 39 | synchronized(children) { 40 | return children.keySet().toArray(new Component[children.size()]); 41 | } 42 | } 43 | 44 | public void add(Component child, Constraint... constraints) { 45 | synchronized(children) { 46 | Container parent = child.getParent(); 47 | if(parent != null && parent.hasChild(child)) 48 | parent.remove(child); 49 | children.put(child, constraints); 50 | if(!enabled) 51 | child.setEnabled(false); 52 | if(!visible) 53 | child.setVisible(false); 54 | child.setParent(this); 55 | child.setTheme(getTheme()); 56 | 57 | layoutChildren(); 58 | } 59 | } 60 | 61 | @Override 62 | public Constraint[] getConstraints(Component child) { 63 | if(child == null) 64 | throw new NullPointerException(); 65 | synchronized(children) { 66 | Constraint[] constraints = children.get(child); 67 | return constraints != null ? constraints : new Constraint[0]; 68 | } 69 | } 70 | 71 | public Component getChildAt(int x, int y) { 72 | synchronized(children) { 73 | for(Component child : children.keySet()) 74 | if(child.getArea().contains(x, y)) 75 | return child; 76 | return null; 77 | } 78 | } 79 | 80 | public boolean remove(Component child) { 81 | synchronized(children) { 82 | if(children.remove(child) != null) { 83 | layoutChildren(); 84 | return true; 85 | } else 86 | return false; 87 | } 88 | } 89 | 90 | public boolean hasChild(Component child) { 91 | synchronized(children) { 92 | return children.get(child) != null; 93 | } 94 | } 95 | 96 | @Override 97 | public void setTheme(Theme theme) { 98 | super.setTheme(theme); 99 | 100 | synchronized(children) { 101 | for(Component child : children.keySet()) 102 | child.setTheme(theme); 103 | } 104 | } 105 | 106 | @Override 107 | public void layoutChildren() { 108 | synchronized(children) { 109 | Component[] components = children.keySet().toArray( 110 | new Component[children.size()]); 111 | Rectangle[] areas = new Rectangle[components.length]; 112 | for(int i = 0; i < components.length; i++) 113 | areas[i] = components[i].getArea(); 114 | Constraint[][] allConstraints = children.values().toArray( 115 | new Constraint[children.size()][]); 116 | if(getTheme() != null) 117 | layoutManager.reposition(ui.getChildRenderArea(this), areas, 118 | allConstraints); 119 | for(Component child : components) 120 | if(child instanceof Container) 121 | ((Container) child).layoutChildren(); 122 | } 123 | } 124 | 125 | @Override 126 | public void onMousePress(int x, int y, int button) { 127 | super.onMousePress(x, y, button); 128 | synchronized(children) { 129 | for(Component child : children.keySet()) { 130 | if(!child.isVisible()) 131 | continue; 132 | if(!child.getArea().contains(x, y)) { 133 | for(Rectangle area : child.getTheme() 134 | .getUIForComponent(child) 135 | .getInteractableRegions(child)) { 136 | if(area.contains(x - child.getX(), y - child.getY())) { 137 | child.onMousePress(x - child.getX(), 138 | y - child.getY(), button); 139 | return; 140 | } 141 | } 142 | } 143 | } 144 | for(Component child : children.keySet()) { 145 | if(!child.isVisible()) 146 | continue; 147 | if(child.getArea().contains(x, y)) { 148 | child.onMousePress(x - child.getX(), y - child.getY(), 149 | button); 150 | return; 151 | } 152 | 153 | } 154 | } 155 | } 156 | 157 | @Override 158 | public void onMouseRelease(int x, int y, int button) { 159 | super.onMouseRelease(x, y, button); 160 | synchronized(children) { 161 | for(Component child : children.keySet()) { 162 | if(!child.isVisible()) 163 | continue; 164 | if(!child.getArea().contains(x, y)) { 165 | for(Rectangle area : child.getTheme() 166 | .getUIForComponent(child) 167 | .getInteractableRegions(child)) { 168 | if(area.contains(x - child.getX(), y - child.getY())) { 169 | child.onMouseRelease(x - child.getX(), 170 | y - child.getY(), button); 171 | return; 172 | } 173 | } 174 | } 175 | } 176 | for(Component child : children.keySet()) { 177 | if(!child.isVisible()) 178 | continue; 179 | if(child.getArea().contains(x, y)) { 180 | child.onMouseRelease(x - child.getX(), y - child.getY(), 181 | button); 182 | return; 183 | } 184 | 185 | } 186 | } 187 | } 188 | 189 | @Override 190 | public void setEnabled(boolean enabled) { 191 | super.setEnabled(enabled); 192 | enabled = isEnabled(); 193 | synchronized(children) { 194 | for(Component child : children.keySet()) 195 | child.setEnabled(enabled); 196 | } 197 | } 198 | 199 | @Override 200 | public void setVisible(boolean visible) { 201 | super.setVisible(visible); 202 | visible = isVisible(); 203 | synchronized(children) { 204 | for(Component child : children.keySet()) 205 | child.setVisible(visible); 206 | } 207 | } 208 | 209 | @Override 210 | public void update() { 211 | for(Component child : getChildren()) 212 | child.update(); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/BoundedRangeComponent.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | public interface BoundedRangeComponent extends Component { 4 | public enum ValueDisplay { 5 | DECIMAL, 6 | INTEGER, 7 | PERCENTAGE, 8 | NONE 9 | } 10 | 11 | public double getValue(); 12 | 13 | public double getMinimumValue(); 14 | 15 | public double getMaximumValue(); 16 | 17 | public double getIncrement(); 18 | 19 | public ValueDisplay getValueDisplay(); 20 | 21 | public void setValue(double value); 22 | 23 | public void setMinimumValue(double minimumValue); 24 | 25 | public void setMaximumValue(double maximumValue); 26 | 27 | public void setIncrement(double increment); 28 | 29 | public void setValueDisplay(ValueDisplay display); 30 | } 31 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/Button.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | import org.darkstorm.minecraft.gui.listener.ButtonListener; 4 | 5 | public interface Button extends Component, TextComponent { 6 | public void press(); 7 | 8 | public void addButtonListener(ButtonListener listener); 9 | 10 | public void removeButtonListener(ButtonListener listener); 11 | 12 | public ButtonGroup getGroup(); 13 | 14 | public void setGroup(ButtonGroup group); 15 | } 16 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/ButtonGroup.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | public interface ButtonGroup { 4 | public void addButton(Button button); 5 | 6 | public void removeButton(Button button); 7 | 8 | public Button[] getButtons(); 9 | } 10 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/CheckButton.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | public interface CheckButton extends Button, SelectableComponent { 4 | } 5 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/ComboBox.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | import org.darkstorm.minecraft.gui.listener.ComboBoxListener; 4 | 5 | public interface ComboBox extends Component, SelectableComponent { 6 | public String[] getElements(); 7 | 8 | public void setElements(String... elements); 9 | 10 | public int getSelectedIndex(); 11 | 12 | public void setSelectedIndex(int selectedIndex); 13 | 14 | public String getSelectedElement(); 15 | 16 | public void addComboBoxListener(ComboBoxListener listener); 17 | 18 | public void removeComboBoxListener(ComboBoxListener listener); 19 | } 20 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/Component.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | import java.awt.*; 4 | 5 | import org.darkstorm.minecraft.gui.theme.Theme; 6 | 7 | public interface Component { 8 | public Theme getTheme(); 9 | 10 | public void setTheme(Theme theme); 11 | 12 | public void render(); 13 | 14 | public void update(); 15 | 16 | public int getX(); 17 | 18 | public int getY(); 19 | 20 | public int getWidth(); 21 | 22 | public int getHeight(); 23 | 24 | public void setX(int x); 25 | 26 | public void setY(int y); 27 | 28 | public void setWidth(int width); 29 | 30 | public void setHeight(int height); 31 | 32 | public Point getLocation(); 33 | 34 | public Dimension getSize(); 35 | 36 | public Rectangle getArea(); 37 | 38 | public Container getParent(); 39 | 40 | public Color getBackgroundColor(); 41 | 42 | public Color getForegroundColor(); 43 | 44 | public void setBackgroundColor(Color color); 45 | 46 | public void setForegroundColor(Color color); 47 | 48 | public void setParent(Container parent); 49 | 50 | public void onMousePress(int x, int y, int button); 51 | 52 | public void onMouseRelease(int x, int y, int button); 53 | 54 | public void resize(); 55 | 56 | public boolean isVisible(); 57 | 58 | public void setVisible(boolean visible); 59 | 60 | public boolean isEnabled(); 61 | 62 | public void setEnabled(boolean enabled); 63 | } 64 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/Container.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | import org.darkstorm.minecraft.gui.layout.*; 4 | 5 | public interface Container extends Component { 6 | public LayoutManager getLayoutManager(); 7 | 8 | public void setLayoutManager(LayoutManager layoutManager); 9 | 10 | public Component[] getChildren(); 11 | 12 | public void add(Component child, Constraint... constraints); 13 | 14 | public Constraint[] getConstraints(Component child); 15 | 16 | public Component getChildAt(int x, int y); 17 | 18 | public boolean hasChild(Component component); 19 | 20 | public boolean remove(Component child); 21 | 22 | public void layoutChildren(); 23 | } 24 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/DraggableComponent.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | 4 | public interface DraggableComponent extends Component { 5 | public boolean isDragging(); 6 | 7 | public void setDragging(boolean dragging); 8 | } 9 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/Frame.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | 4 | public interface Frame extends Container, DraggableComponent { 5 | public String getTitle(); 6 | 7 | public void setTitle(String title); 8 | 9 | public boolean isPinned(); 10 | 11 | public void setPinned(boolean pinned); 12 | 13 | public boolean isPinnable(); 14 | 15 | public void setPinnable(boolean pinnable); 16 | 17 | public boolean isMinimized(); 18 | 19 | public void setMinimized(boolean minimized); 20 | 21 | public boolean isMinimizable(); 22 | 23 | public void setMinimizable(boolean minimizable); 24 | 25 | public void close(); 26 | 27 | public boolean isClosable(); 28 | 29 | public void setClosable(boolean closable); 30 | } 31 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/Label.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | public interface Label extends TextComponent { 4 | public enum TextAlignment { 5 | CENTER, 6 | LEFT, 7 | RIGHT, 8 | TOP, 9 | BOTTOM 10 | } 11 | 12 | public TextAlignment getHorizontalAlignment(); 13 | 14 | public TextAlignment getVerticalAlignment(); 15 | 16 | public void setHorizontalAlignment(TextAlignment alignment); 17 | 18 | public void setVerticalAlignment(TextAlignment alignment); 19 | } 20 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/Panel.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | public interface Panel extends Container { 4 | } 5 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/ProgressBar.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | public interface ProgressBar extends Component, BoundedRangeComponent { 4 | public boolean isIndeterminate(); 5 | 6 | public void setIndeterminate(boolean indeterminate); 7 | } 8 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/RadioButton.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | public interface RadioButton extends Button, SelectableComponent { 4 | } 5 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/SelectableComponent.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | import org.darkstorm.minecraft.gui.listener.SelectableComponentListener; 4 | 5 | public interface SelectableComponent extends Component { 6 | public boolean isSelected(); 7 | 8 | public void setSelected(boolean selected); 9 | 10 | public void addSelectableComponentListener(SelectableComponentListener listener); 11 | 12 | public void removeSelectableComponentListener(SelectableComponentListener listener); 13 | } 14 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/Slider.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | import org.darkstorm.minecraft.gui.listener.SliderListener; 4 | 5 | public interface Slider extends Component, TextComponent, BoundedRangeComponent { 6 | public String getContentSuffix(); 7 | 8 | public boolean isValueChanging(); 9 | 10 | public void setContentSuffix(String suffix); 11 | 12 | public void setValueChanging(boolean changing); 13 | 14 | public void addSliderListener(SliderListener listener); 15 | 16 | public void removeSliderListener(SliderListener listener); 17 | } 18 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/TextComponent.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component; 2 | 3 | public interface TextComponent extends Component { 4 | public String getText(); 5 | 6 | public void setText(String text); 7 | } 8 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/basic/BasicButton.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component.basic; 2 | 3 | import org.darkstorm.minecraft.gui.component.*; 4 | import org.darkstorm.minecraft.gui.listener.*; 5 | 6 | public class BasicButton extends AbstractComponent implements Button { 7 | protected String text = ""; 8 | protected ButtonGroup group; 9 | 10 | public BasicButton() { 11 | } 12 | 13 | public BasicButton(String text) { 14 | this.text = text; 15 | } 16 | 17 | @Override 18 | public String getText() { 19 | return text; 20 | } 21 | 22 | @Override 23 | public void setText(String text) { 24 | this.text = text; 25 | } 26 | 27 | @Override 28 | public void press() { 29 | for(ComponentListener listener : getListeners()) 30 | ((ButtonListener) listener).onButtonPress(this); 31 | } 32 | 33 | @Override 34 | public void addButtonListener(ButtonListener listener) { 35 | addListener(listener); 36 | } 37 | 38 | @Override 39 | public void removeButtonListener(ButtonListener listener) { 40 | removeListener(listener); 41 | } 42 | 43 | @Override 44 | public ButtonGroup getGroup() { 45 | return group; 46 | } 47 | 48 | @Override 49 | public void setGroup(ButtonGroup group) { 50 | this.group = group; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/org/darkstorm/minecraft/gui/component/basic/BasicButtonGroup.java: -------------------------------------------------------------------------------- 1 | package org.darkstorm.minecraft.gui.component.basic; 2 | 3 | import java.util.*; 4 | 5 | import org.darkstorm.minecraft.gui.component.*; 6 | 7 | public class BasicButtonGroup implements ButtonGroup { 8 | private List