diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ed18dbdd4..bcb57dd38 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,35 +1,183 @@ +[![Creative Commons License](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](#credits) + # Content -1. [General rules](#general-rules) +1. [Code of Conduct](#code-of-conduct) 2. [Issues](#issues) 3. [Pull Requests](#pull-requests) -4. [Tutorials](#tutorials) +4. [Commits](#commits) +5. [Credits](#credits) + +# Code of Conduct +- **Think before you react.** If you disagree strongly, consider giving it a few minutes before responding. + +- **Ask questions, don't make demands.** ("What do you think about trying...?" rather than "Don’t do...!!!") + +- **Don't insult.** Avoid using terms that could be seen as referring to personal traits. ("dumb", "stupid"). Assume everyone is attractive, intelligent, and well-meaning. + +- **Be explicit.** Remember people don't always understand your intentions online. + +- **Don't use hyperbole.** ("always", "never", "endlessly", "nothing") -# General rules -- **Use proper grammar.** If no one can read it, no one can help you. -- **Use proper Markdown.** If you have never used markdown before, you can [learn it in 3 minutes](https://guides.github.com/features/mastering-markdown/). +- **Use emoji to clarify tone.** (":sparkles::sparkles: Looks good :+1: :sparkles::sparkles:" rather than "Looks good.") # Issues -- [**Watch the tutorial**](https://www.youtube.com/watch?v=TJlYiMp8FuY) if you have never used GitHub Issues before. It only takes 3 minutes! +## Before writing an Issue + +[**Watch this tutorial**](https://www.youtube.com/watch?v=TJlYiMp8FuY) if you have never used GitHub's Issue tracker before. It only takes 3 minutes! + [![](https://i.ytimg.com/vi/TJlYiMp8FuY/mqdefault.jpg)](https://www.youtube.com/watch?v=TJlYiMp8FuY) -- **Check existing issues** for your issue. Duplicating an issue is slower for both parties so search through open and closed issues to see if what you’re running into has been addressed already. -- **Create an issue** for your issue. Don't post a comment on an existing issue. Only use comments to *add information* to existing issues. -- **Create multiple issues** if you have multiple issues. Don't put every single problem you ever had in life into one issue. That makes it impossible *organize your issues* and will likely get your issue ignored or removed. -- **Be clear** about your problem: What was the expected outcome, what happened instead? Detail how someone else can recreate the problem. + +#### Always search your Issue before opening a new one. Creating duplicates is slower for everyone! + +## Writing an Issue +### The Title + +- #### Others should be able to guess what the Issue is about by reading its title. + +- Try to use less than 40 characters. + +- **Avoid writing `Wurst`** in the title. It is obvious that your Issue is about Wurst. + +- If the title gets too long, remove words like `the` and `a`. + +- **Don't put a dot at the end.** It's a headline, not a sentence. + +#### Examples: + +- "".help 1" command throwing NullPointerException" :white_check_mark: **good title** + +- "WUrst bug FIX UP!!1 (╯°□°)╯︵ ┻━┻" :x: **bad title** + +### The Body + +- #### Don't include opinions or judgements, only information. + - "I found a bug." :white_check_mark: **good** + - "I love/hate Wurst and found a bug." :x: **bad** + +- **Use proper grammar & Markdown.** If no one can read it, no one can help you. +If you have never used markdown before, you can [learn it in 3 minutes](https://guides.github.com/features/mastering-markdown/). + +- **Don't put multiple Issues into one issue.** That makes them impossible organize and will likely get your issue ignored or removed. + +- **Be clear** + - **about problems:** What was the expected outcome, what happened instead? Detail how someone else can reproduce the problem; + - **about suggestions:** What will your feature do, how will it help, why is it useful? + +- **Include screenshots** if your Issue is about something visible. Embed the screenshots directly into your Issue, don't link to external images. + - **Include system details** like the Java version and operating system you’re using. -- **Include screenshots** if your problem is visible. Drag & drop the image directly into your issue. -- **Paste error output** or logs in your issue or in a [Gist](https://gist.github.com/). If pasting them in the issue, wrap it in three backticks so that it renders nicely. + +- **Paste error output** like Java stacktraces or Minecraft launcher logs into your Issue. Wrap it into a Markdown code block, like this: + +
```
+java.lang.NullPointerException: null
+  at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:89)
+	at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:425)
+	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:406)
+	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:367)
+	at org.apache.logging.log4j.core.Logger.log(Logger.java:110)
+```
+ +#### Always include stacktraces or crash logs when reporting errors or crashes. + +If it's too long to paste it into the Issue, paste it into a [Gist](https://gist.github.com/). + +#### Examples: + +> :white_check_mark: **good Issue** +> +> # Description +> After typing the command `.nuker mode flat` while Nuker was still enabled and in Smash mode, an exception was thrown (see below). +> +> This seems to happen every time, but only if Nuker is enabled. +> +> # Stacktrace +> ``` +> java.lang.ArrayIndexOutOfBoundsException: 1 +> at tk.wurst_client.command.commands.NukerMod.onEnable(NukerMod.java:34) +> at tk.wurst_client.command.CommandManager.onSentMessage(CommandManager.java:40) +> at tk.wurst_client.event.EventManager.fireEvent(EventManager.java:137) +> at net.minecraft.client.entity.EntityPlayerSP.sendChatMessage(EntityPlayerSP.java:292) +> at net.minecraft.client.gui.GuiScreen.func_175281_b(GuiScreen.java:487) +> at net.minecraft.client.gui.GuiScreen.func_175275_f(GuiScreen.java:477) +> at net.minecraft.client.gui.GuiChat.keyTyped(GuiChat.java:132) +> at net.minecraft.client.gui.GuiScreen.handleKeyboardInput(GuiScreen.java:617) +> at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:568) +> at net.minecraft.client.Minecraft.runTick(Minecraft.java:2024) +> at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1354) +> at net.minecraft.client.Minecraft.run(Minecraft.java:468) +> at net.minecraft.client.main.Main.main(Main.java:127) +> ``` +> +> # System details +> - OS: Windows 8.1 (x86) +> - Java version: 1.8.0_31 (Oracle Corporation) +> - Wurst version: 1.9 (latest: 1.9) + +--- +> :x: **bad Issue** +> +> Me got error, this sooooooo buggy!!1!!!11!!11111!!!!!!!!!!!!!!!!!!!!!!!1!! +> (╯°□°)╯︵ ┻━┻ +> Fix ASAP and add OptiFine or I will uninstall!!!! +> +> PS subscribe me on YouTube and Facebook + +## After writing an Issue + +- **Respond to questions**, especially if you get the `more info required` label. + +- **Don't get angry** or needy if your Issue gets rejected. We are free to reject any Issue for any reason. # Pull Requests +> **Note:** There haven't been many Pull Requests yet, so these guidelines are mostly based on predictions rather than experience. + - [**Read the tutorial**](https://guides.github.com/activities/forking/) if you have never forked a repository before. [![](https://github-images.s3.amazonaws.com/help/bootcamp/Bootcamp-Fork.png)](https://guides.github.com/activities/forking/) + - **Fork the repository** and clone it locally. + - **Pull in changes** from the original often so that you stay up to date. That way, when you submit your pull request, merge conflicts will be less likely. + - **Create a branch** for your edits. + - **Be clear** about what problem is occurring and how someone can recreate that problem or why your feature will help. Then be equally as clear about the steps you took to make your changes. + - **It’s best to test.** Run your changes against any existing tests if they exist and create new ones when needed. Whether tests exist or not, make sure your changes don’t break the existing project. + - **Include screenshots** of the before and after if your changes include visible differences. Drag and drop the images into the body of your pull request. + - **Keep the style** of the project to the best of your abilities. This may mean using indents, semi colons or comments differently than you would in your own repository, but makes it easier for the maintainer to merge, others to understand and maintain in the future. -# Tutorials -- [How to write the perfect Pull Request](https://github.com/blog/1943-how-to-write-the-perfect-pull-request) -- [Contributing to Open Source on GitHub](https://guides.github.com/activities/contributing-to-open-source/#contributing) +# Commits + +- Use present tense & imperative mood. + - "Add feature" :white_check_mark: **good** + - "Added feature" :x: **bad** + - "Adds feature" :x: **bad** +- Consider starting the commit message with an applicable emoji: + - :bug: `:bug:` when fixing bugs + - :rocket: `:rocket:` when improving performance + - :gem: `:gem:` when cleaning up code + - :memo: `:memo:` when writing docs + - :bar_chart: `:bar_chart:` when dealing with Google Analytics + - :art: `:art:` when designing GUIs etc. + - :lock: `:lock:` when dealing with security +- When fixing/implementing Issues, include the Issue number. That will close the Issues automatically. + - "Fix #272" (for bugs) :white_check_mark: **good** + - "Resolve #272" (for features) :white_check_mark: **good** + - "Fix error in .nuker that was reported in #272" :x: **bad** +- When fixing [anonymous error reports](https://www.wurst-client.tk/error-reports) (Wurst v1.12 and higher), include the ID. + - "Fix error report mosz7w34tmagrh8qw3mngwwmn5ww" :white_check_mark: **good** + - "Fix an error I found on wurst-client.tk/error-reports" :x: **bad** + +# Credits +[![Creative Commons License](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/) + +These guidelines by Alexander01998 are licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). + +These guidelines are partially based on the following guides and guidelines: +- [thoughtbot Inc: Code Review](https://github.com/thoughtbot/guides/tree/master/code-review) +- [Atom editor: Contributing guidelines](https://github.com/atom/atom/blob/master/CONTRIBUTING.md) +- [The GitHub Blog: How to write the perfect Pull Request](https://github.com/blog/1943-how-to-write-the-perfect-pull-request) +- [AngularJS: Contributing guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md) diff --git a/README.md b/README.md index 101eb7c39..8f2eda9dd 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,38 @@ -# Wurst-Client -![Wurst Client logo](Wurst%20logo/wurst_1011x256.png) +# Wurst Client![](https://ga-beacon.appspot.com/UA-52838431-1/GitHub/README.md?pixel) +![Wurst Client logo](https://cloud.githubusercontent.com/assets/10100202/6868084/c764a252-d488-11e4-94cf-1daa5e398c35.png) -## About -The Wurst Hack Client for Minecraft is packed full of the latest and most exciting mods, commands and other features. It contains over 70 mods and over 20 commands that let you rule the game. +[![downloads](https://drive.google.com/uc?id=0B2YeSS9tm5zLMF9NWjNZYnNqSTA)](https://github.com/Wurst-Imperium/Wurst-Client/releases/latest) +[![latest release](https://img.shields.io/github/release/Wurst-Imperium/Wurst-Client.svg?label=latest%20release)](https://github.com/Wurst-Imperium/Wurst-Client/releases/latest) +[![mods](https://img.shields.io/badge/mods-90+-brightgreen.svg)](#) +[![commands](https://img.shields.io/badge/commands-35+-brightgreen.svg)](#) +[![hot, fresh & sexy](https://img.shields.io/badge/hot,%20fresh%20&%20sexy-100%-ff69e3.svg)](http://wizardhax.com/wurst) +[![](https://img.shields.io/github/license/Wurst-Imperium/Wurst-Client.svg)](https://github.com/Wurst-Imperium/Wurst-Client/blob/master/LICENSE) +[![analytics](https://img.shields.io/badge/analytics-GA-blue.svg)](https://github.com/igrigorik/ga-beacon) + +## About :information_source: +The Wurst Client is a Hack Client for Minecraft, packed full of the latest and most exciting mods, commands and other features. All of the mods and commands are instantly deployable at any moment, through buttons, keybinds and even automatic scripts. *You rule the game!* + +## :sparkles::sparkles::sparkles: Special Features :sparkles::sparkles::sparkles: +### Secure AltManager :closed_lock_with_key: +Wurst comes packed with a full featured Alt Manager that supports both premium and cracked accounts. It's the only Alt Manager out there that uses modern encryption algorithms to ensure your alts are stored securely. + +### Custom AutoBuild :construction: +Wurst is the only client containing an AutoBuild mod that is fully customizable. You can create your very own templates using the popular JSON language or download some samples from the Wurst Client website. It also comes with 7 templates pre-installed, so you can instantly start using it. + +### Wurst-Bot :floppy_disk: +Wurst-Bot allows you to automate everything! It can grief for you, fight for you, or just spam stuff the chat. You can either run it from the command-line or make yourself a custom Wurst-Bot launcher in nearly any language. Since DarkBot is discontinued, this is yet another Wurst feature that you won't find in any other client. + +### Made with Love! :heart: +Wurst is one of the few clients out there that is **not** made for the money - I actually care about this client. It is my goal to create a client that is absolutely perfect - and I work day & night to achieve this goal. + +So what are you waiting for? Grab a [download](https://github.com/Wurst-Imperium/Wurst-Client/releases/latest), have a play and enjoy the smooth and relaxing gameplay. + +## Issues :worried: +If you found a bug or you have a suggestion, use the GitHub Issue tracker. Keep the [contributing guidelines](/CONTRIBUTING.md) in mind - Issues that violate them will be removed with no mercy. + +## Contributing :computer: +Want to help with the development? Awesome! Just click the[`fork`](https://github.com/Wurst-Imperium/Wurst-Client/fork) button, make your changes and create a Pull Request. Again, keep the [contributing guidelines](/CONTRIBUTING.md) in mind. + +Need inspiration on what to implement? Check out the [list of suggestions](https://github.com/Wurst-Imperium/Wurst-Client/issues?q=is%3Aopen+label%3Aconfirmed+label%3Aenhancement). + +If you have trouble setting it up in Eclipse, read the wiki page ["Debugging Wurst in Eclipse"](https://github.com/Wurst-Imperium/Wurst-Client/wiki/Debugging-Wurst-in-Eclipse). diff --git a/Wurst logo/.gitignore b/Wurst Client/src/assets/minecraft/wurst/.gitignore similarity index 100% rename from Wurst logo/.gitignore rename to Wurst Client/src/assets/minecraft/wurst/.gitignore diff --git a/Wurst Client/src/assets/minecraft/wurst/bug.png b/Wurst Client/src/assets/minecraft/wurst/bug.png new file mode 100644 index 000000000..9e39e0072 Binary files /dev/null and b/Wurst Client/src/assets/minecraft/wurst/bug.png differ diff --git a/Wurst Client/src/assets/minecraft/wurst/dancingtaco1.png b/Wurst Client/src/assets/minecraft/wurst/dancingtaco1.png new file mode 100644 index 000000000..05bb6d793 Binary files /dev/null and b/Wurst Client/src/assets/minecraft/wurst/dancingtaco1.png differ diff --git a/Wurst Client/src/assets/minecraft/wurst/dancingtaco2.png b/Wurst Client/src/assets/minecraft/wurst/dancingtaco2.png new file mode 100644 index 000000000..fa25d26ba Binary files /dev/null and b/Wurst Client/src/assets/minecraft/wurst/dancingtaco2.png differ diff --git a/Wurst Client/src/assets/minecraft/wurst/dancingtaco3.png b/Wurst Client/src/assets/minecraft/wurst/dancingtaco3.png new file mode 100644 index 000000000..eb07b6a29 Binary files /dev/null and b/Wurst Client/src/assets/minecraft/wurst/dancingtaco3.png differ diff --git a/Wurst Client/src/assets/minecraft/wurst/dancingtaco4.png b/Wurst Client/src/assets/minecraft/wurst/dancingtaco4.png new file mode 100644 index 000000000..a1d71e2e0 Binary files /dev/null and b/Wurst Client/src/assets/minecraft/wurst/dancingtaco4.png differ diff --git a/Wurst Client/src/assets/minecraft/wurst/error-report.md b/Wurst Client/src/assets/minecraft/wurst/error-report.md new file mode 100644 index 000000000..b3ab5f644 --- /dev/null +++ b/Wurst Client/src/assets/minecraft/wurst/error-report.md @@ -0,0 +1,15 @@ +> This is an auto-generated error report for the [Wurst Client](https://www.wurst-client.tk). + +# Description +desc + +# Stacktrace +``` +trace +``` + +# System details +- OS: os +- Java version: java +- Wurst version: wurst +- Timestamp: time \ No newline at end of file diff --git a/Wurst Client/src/assets/minecraft/wurst/santa_hat.png b/Wurst Client/src/assets/minecraft/wurst/santa_hat.png new file mode 100644 index 000000000..ffbfa98c4 Binary files /dev/null and b/Wurst Client/src/assets/minecraft/wurst/santa_hat.png differ diff --git a/Wurst Client/src/assets/minecraft/wurst/updater b/Wurst Client/src/assets/minecraft/wurst/updater new file mode 100644 index 000000000..56a6051ca --- /dev/null +++ b/Wurst Client/src/assets/minecraft/wurst/updater @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/Wurst logo/wurst_505x128.png b/Wurst Client/src/assets/minecraft/wurst/wurst_128.png similarity index 100% rename from Wurst logo/wurst_505x128.png rename to Wurst Client/src/assets/minecraft/wurst/wurst_128.png diff --git a/Wurst Client/src/assets/minecraft/wurst/wurst_380.png b/Wurst Client/src/assets/minecraft/wurst/wurst_380.png new file mode 100644 index 000000000..05949d259 Binary files /dev/null and b/Wurst Client/src/assets/minecraft/wurst/wurst_380.png differ diff --git a/Wurst Client/src/assets/minecraft/wurst/wurst_loading.png b/Wurst Client/src/assets/minecraft/wurst/wurst_loading.png new file mode 100644 index 000000000..6803a2846 Binary files /dev/null and b/Wurst Client/src/assets/minecraft/wurst/wurst_loading.png differ diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/AbstractGuiManager.java b/Wurst Client/src/org/darkstorm/minecraft/gui/AbstractGuiManager.java new file mode 100644 index 000000000..be054b4ce --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/AbstractGuiManager.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013, DarkStorm (darkstorm@evilminecraft.net) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.darkstorm.minecraft.gui; + +import static org.lwjgl.opengl.GL11.GL_BLEND; +import static org.lwjgl.opengl.GL11.GL_CULL_FACE; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL11.glDisable; +import static org.lwjgl.opengl.GL11.glEnable; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.darkstorm.minecraft.gui.component.Frame; +import org.darkstorm.minecraft.gui.theme.Theme; + +import tk.wurst_client.WurstClient; + +/** + * Minecraft GUI API + * + * @author DarkStorm (darkstorm@evilminecraft.net) + */ +public abstract class AbstractGuiManager implements GuiManager +{ + private final List frames; + + protected Theme theme; + + public AbstractGuiManager() + { + frames = new CopyOnWriteArrayList(); + } + + @Override + public abstract void setup(); + + @Override + public void addFrame(Frame frame) + { + frame.setTheme(theme); + frames.add(0, frame); + } + + @Override + public void removeFrame(Frame frame) + { + frames.remove(frame); + } + + @Override + public Frame[] getFrames() + { + return frames.toArray(new Frame[frames.size()]); + } + + @Override + public void bringForward(Frame frame) + { + if(frames.remove(frame)) + frames.add(0, frame); + } + + @Override + public Theme getTheme() + { + return theme; + } + + @Override + public void setTheme(Theme theme) + { + this.theme = theme; + for(Frame frame : frames) + frame.setTheme(theme); + resizeComponents(); + } + + protected abstract void resizeComponents(); + + @Override + public void render() + { + Frame[] frames = getFrames(); + for(int i = frames.length - 1; i >= 0; i--) + frames[i].render(); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + WurstClient.INSTANCE.fileManager.saveGUI(getFrames()); + } + + @Override + public void renderPinned() + { + Frame[] frames = getFrames(); + for(int i = frames.length - 1; i >= 0; i--) + if(frames[i].isPinned()) + frames[i].render(); + } + + @Override + public void update() + { + Frame[] frames = getFrames(); + for(int i = frames.length - 1; i >= 0; i--) + frames[i].update(); + } +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/GuiManager.java b/Wurst Client/src/org/darkstorm/minecraft/gui/GuiManager.java new file mode 100644 index 000000000..7d424e96d --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/GuiManager.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, DarkStorm (darkstorm@evilminecraft.net) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.darkstorm.minecraft.gui; + +import org.darkstorm.minecraft.gui.component.Frame; +import org.darkstorm.minecraft.gui.theme.Theme; + +/** + * Minecraft GUI API + * + * @author DarkStorm (darkstorm@evilminecraft.net) + */ +public interface GuiManager +{ + public void setup(); + + public void addFrame(Frame frame); + + public void removeFrame(Frame frame); + + public Frame[] getFrames(); + + public void bringForward(Frame frame); + + public Theme getTheme(); + + public void setTheme(Theme theme); + + public void render(); + + public void renderPinned(); + + public void update(); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/AbstractComponent.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/AbstractComponent.java new file mode 100644 index 000000000..ccc4425a9 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/AbstractComponent.java @@ -0,0 +1,262 @@ +package org.darkstorm.minecraft.gui.component; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.darkstorm.minecraft.gui.listener.ComponentListener; +import org.darkstorm.minecraft.gui.theme.ComponentUI; +import org.darkstorm.minecraft.gui.theme.Theme; + +public abstract class AbstractComponent implements Component +{ + private Container parent = null; + private Theme theme; + + protected Rectangle area = new Rectangle(0, 0, 0, 0); + protected ComponentUI ui; + protected Color foreground, background; + protected boolean enabled = true, visible = true; + + private List listeners = + new CopyOnWriteArrayList(); + + @Override + public void render() + { + if(ui == null) + return; + ui.render(this); + } + + @Override + public void update() + { + if(ui == null) + return; + ui.handleUpdate(this); + } + + protected ComponentUI getUI() + { + return theme.getUIForComponent(this); + } + + @Override + public void onMousePress(int x, int y, int button) + { + if(ui != null) + for(Rectangle area : ui.getInteractableRegions(this)) + if(area.contains(x, y)) + { + ui.handleInteraction(this, new Point(x, y), button); + break; + } + } + + @Override + public void onMouseRelease(int x, int y, int button) + {} + + @Override + public Theme getTheme() + { + return theme; + } + + @Override + public void setTheme(Theme theme) + { + Theme oldTheme = this.theme; + this.theme = theme; + if(theme == null) + { + ui = null; + foreground = null; + background = null; + return; + } + + ui = getUI(); + boolean changeArea; + if(oldTheme != null) + { + Dimension defaultSize = + oldTheme.getUIForComponent(this).getDefaultSize(this); + changeArea = + area.width == defaultSize.width + && area.height == defaultSize.height; + }else + changeArea = area.equals(new Rectangle(0, 0, 0, 0)); + if(changeArea) + { + Dimension defaultSize = ui.getDefaultSize(this); + area = + new Rectangle(area.x, area.y, defaultSize.width, + defaultSize.height); + } + foreground = ui.getDefaultForegroundColor(this); + background = ui.getDefaultBackgroundColor(this); + } + + @Override + public int getX() + { + return area.x; + } + + @Override + public int getY() + { + return area.y; + } + + @Override + public int getWidth() + { + return area.width; + } + + @Override + public int getHeight() + { + return area.height; + } + + @Override + public void setX(int x) + { + area.x = x; + } + + @Override + public void setY(int y) + { + area.y = y; + } + + @Override + public void setWidth(int width) + { + area.width = width; + } + + @Override + public void setHeight(int height) + { + area.height = height; + } + + @Override + public Color getBackgroundColor() + { + return background; + } + + @Override + public Color getForegroundColor() + { + return foreground; + } + + @Override + public void setBackgroundColor(Color color) + { + background = color; + } + + @Override + public void setForegroundColor(Color color) + { + foreground = color; + } + + @Override + public Point getLocation() + { + return area.getLocation(); + } + + @Override + public Dimension getSize() + { + return area.getSize(); + } + + @Override + public Rectangle getArea() + { + return area; + } + + @Override + public Container getParent() + { + return parent; + } + + @Override + public void setParent(Container parent) + { + if(!parent.hasChild(this) || this.parent != null + && this.parent.hasChild(this)) + throw new IllegalArgumentException(); + this.parent = parent; + } + + @Override + public void resize() + { + Dimension defaultDimension = ui.getDefaultSize(this); + setWidth(defaultDimension.width); + setHeight(defaultDimension.height); + } + + @Override + public boolean isEnabled() + { + return enabled; + } + + @Override + public void setEnabled(boolean enabled) + { + if(parent != null && !parent.isEnabled()) + this.enabled = false; + else + this.enabled = enabled; + } + + @Override + public boolean isVisible() + { + return visible; + } + + @Override + public void setVisible(boolean visible) + { + if(parent != null && !parent.isVisible()) + this.visible = false; + else + this.visible = visible; + } + + protected void addListener(ComponentListener listener) + { + listeners.add(listener); + } + + protected void removeListener(ComponentListener listener) + { + listeners.remove(listener); + } + + protected ComponentListener[] getListeners() + { + return listeners.toArray(new ComponentListener[listeners.size()]); + } +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/AbstractContainer.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/AbstractContainer.java new file mode 100644 index 000000000..ea915fc55 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/AbstractContainer.java @@ -0,0 +1,257 @@ +package org.darkstorm.minecraft.gui.component; + +import java.awt.Rectangle; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.darkstorm.minecraft.gui.layout.BasicLayoutManager; +import org.darkstorm.minecraft.gui.layout.Constraint; +import org.darkstorm.minecraft.gui.layout.LayoutManager; +import org.darkstorm.minecraft.gui.theme.Theme; + +public abstract class AbstractContainer extends AbstractComponent implements + Container +{ + private final Map children = + new LinkedHashMap(); + + private LayoutManager layoutManager = new BasicLayoutManager(); + + @Override + public void render() + { + super.render(); + + synchronized(children) + { + for(Component child : children.keySet()) + child.render(); + } + } + + @Override + public LayoutManager getLayoutManager() + { + return layoutManager; + } + + @Override + public void setLayoutManager(LayoutManager layoutManager) + { + if(layoutManager == null) + layoutManager = new BasicLayoutManager(); + this.layoutManager = layoutManager; + + layoutChildren(); + } + + @Override + public Component[] getChildren() + { + synchronized(children) + { + return children.keySet().toArray(new Component[children.size()]); + } + } + + @Override + public void add(Component child, Constraint... constraints) + { + synchronized(children) + { + Container parent = child.getParent(); + if(parent != null && parent.hasChild(child)) + parent.remove(child); + children.put(child, constraints); + if(!enabled) + child.setEnabled(false); + if(!visible) + child.setVisible(false); + child.setParent(this); + child.setTheme(getTheme()); + + layoutChildren(); + } + } + + @Override + public Constraint[] getConstraints(Component child) + { + if(child == null) + throw new NullPointerException(); + synchronized(children) + { + Constraint[] constraints = children.get(child); + return constraints != null ? constraints : new Constraint[0]; + } + } + + @Override + public Component getChildAt(int x, int y) + { + synchronized(children) + { + for(Component child : children.keySet()) + if(child.getArea().contains(x, y)) + return child; + return null; + } + } + + @Override + public boolean remove(Component child) + { + synchronized(children) + { + if(children.remove(child) != null) + { + layoutChildren(); + return true; + }else + return false; + } + } + + @Override + public boolean hasChild(Component child) + { + synchronized(children) + { + return children.get(child) != null; + } + } + + @Override + public void setTheme(Theme theme) + { + super.setTheme(theme); + + synchronized(children) + { + for(Component child : children.keySet()) + child.setTheme(theme); + } + } + + @Override + public void layoutChildren() + { + synchronized(children) + { + Component[] components = + children.keySet().toArray(new Component[children.size()]); + Rectangle[] areas = new Rectangle[components.length]; + for(int i = 0; i < components.length; i++) + areas[i] = components[i].getArea(); + Constraint[][] allConstraints = + children.values().toArray(new Constraint[children.size()][]); + if(getTheme() != null) + layoutManager.reposition(ui.getChildRenderArea(this), areas, + allConstraints); + for(Component child : components) + if(child instanceof Container) + ((Container)child).layoutChildren(); + } + } + + @Override + public void onMousePress(int x, int y, int button) + { + super.onMousePress(x, y, button); + synchronized(children) + { + for(Component child : children.keySet()) + { + if(!child.isVisible()) + continue; + if(!child.getArea().contains(x, y)) + for(Rectangle area : child.getTheme() + .getUIForComponent(child).getInteractableRegions(child)) + if(area.contains(x - child.getX(), y - child.getY())) + { + child.onMousePress(x - child.getX(), + y - child.getY(), button); + return; + } + } + for(Component child : children.keySet()) + { + if(!child.isVisible()) + continue; + if(child.getArea().contains(x, y)) + { + child.onMousePress(x - child.getX(), y - child.getY(), + button); + return; + } + + } + } + } + + @Override + public void onMouseRelease(int x, int y, int button) + { + super.onMouseRelease(x, y, button); + synchronized(children) + { + for(Component child : children.keySet()) + { + if(!child.isVisible()) + continue; + if(!child.getArea().contains(x, y)) + for(Rectangle area : child.getTheme() + .getUIForComponent(child).getInteractableRegions(child)) + if(area.contains(x - child.getX(), y - child.getY())) + { + child.onMouseRelease(x - child.getX(), + y - child.getY(), button); + return; + } + } + for(Component child : children.keySet()) + { + if(!child.isVisible()) + continue; + if(child.getArea().contains(x, y)) + { + child.onMouseRelease(x - child.getX(), y - child.getY(), + button); + return; + } + + } + } + } + + @Override + public void setEnabled(boolean enabled) + { + super.setEnabled(enabled); + enabled = isEnabled(); + synchronized(children) + { + for(Component child : children.keySet()) + child.setEnabled(enabled); + } + } + + @Override + public void setVisible(boolean visible) + { + super.setVisible(visible); + visible = isVisible(); + synchronized(children) + { + for(Component child : children.keySet()) + child.setVisible(visible); + } + } + + @Override + public void update() + { + for(Component child : getChildren()) + child.update(); + } +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/BoundedRangeComponent.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/BoundedRangeComponent.java new file mode 100644 index 000000000..4bb01df25 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/BoundedRangeComponent.java @@ -0,0 +1,32 @@ +package org.darkstorm.minecraft.gui.component; + +public interface BoundedRangeComponent extends Component +{ + public enum ValueDisplay + { + DECIMAL, + INTEGER, + PERCENTAGE, + NONE + } + + public double getValue(); + + public double getMinimumValue(); + + public double getMaximumValue(); + + public double getIncrement(); + + public ValueDisplay getValueDisplay(); + + public void setValue(double value); + + public void setMinimumValue(double minimumValue); + + public void setMaximumValue(double maximumValue); + + public void setIncrement(double increment); + + public void setValueDisplay(ValueDisplay display); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/Button.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Button.java new file mode 100644 index 000000000..6a0e44759 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Button.java @@ -0,0 +1,20 @@ +package org.darkstorm.minecraft.gui.component; + +import org.darkstorm.minecraft.gui.listener.ButtonListener; + +public interface Button extends Component, TextComponent +{ + public void press(); + + public void addButtonListener(ButtonListener listener); + + public void removeButtonListener(ButtonListener listener); + + public ButtonGroup getGroup(); + + public void setGroup(ButtonGroup group); + + public String getDescription(); + + public void setDescription(String description); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/ButtonGroup.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/ButtonGroup.java new file mode 100644 index 000000000..245ec0eee --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/ButtonGroup.java @@ -0,0 +1,10 @@ +package org.darkstorm.minecraft.gui.component; + +public interface ButtonGroup +{ + public void addButton(Button button); + + public void removeButton(Button button); + + public Button[] getButtons(); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/CheckButton.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/CheckButton.java new file mode 100644 index 000000000..367ea469e --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/CheckButton.java @@ -0,0 +1,4 @@ +package org.darkstorm.minecraft.gui.component; + +public interface CheckButton extends Button, SelectableComponent +{} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/ComboBox.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/ComboBox.java new file mode 100644 index 000000000..cffe6892d --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/ComboBox.java @@ -0,0 +1,20 @@ +package org.darkstorm.minecraft.gui.component; + +import org.darkstorm.minecraft.gui.listener.ComboBoxListener; + +public interface ComboBox extends Component, SelectableComponent +{ + public String[] getElements(); + + public void setElements(String... elements); + + public int getSelectedIndex(); + + public void setSelectedIndex(int selectedIndex); + + public String getSelectedElement(); + + public void addComboBoxListener(ComboBoxListener listener); + + public void removeComboBoxListener(ComboBoxListener listener); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/Component.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Component.java new file mode 100644 index 000000000..e7f8e08fc --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Component.java @@ -0,0 +1,67 @@ +package org.darkstorm.minecraft.gui.component; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; + +import org.darkstorm.minecraft.gui.theme.Theme; + +public interface Component +{ + public Theme getTheme(); + + public void setTheme(Theme theme); + + public void render(); + + public void update(); + + public int getX(); + + public int getY(); + + public int getWidth(); + + public int getHeight(); + + public void setX(int x); + + public void setY(int y); + + public void setWidth(int width); + + public void setHeight(int height); + + public Point getLocation(); + + public Dimension getSize(); + + public Rectangle getArea(); + + public Container getParent(); + + public Color getBackgroundColor(); + + public Color getForegroundColor(); + + public void setBackgroundColor(Color color); + + public void setForegroundColor(Color color); + + public void setParent(Container parent); + + public void onMousePress(int x, int y, int button); + + public void onMouseRelease(int x, int y, int button); + + public void resize(); + + public boolean isVisible(); + + public void setVisible(boolean visible); + + public boolean isEnabled(); + + public void setEnabled(boolean enabled); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/Container.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Container.java new file mode 100644 index 000000000..1a12409aa --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Container.java @@ -0,0 +1,25 @@ +package org.darkstorm.minecraft.gui.component; + +import org.darkstorm.minecraft.gui.layout.Constraint; +import org.darkstorm.minecraft.gui.layout.LayoutManager; + +public interface Container extends Component +{ + public LayoutManager getLayoutManager(); + + public void setLayoutManager(LayoutManager layoutManager); + + public Component[] getChildren(); + + public void add(Component child, Constraint... constraints); + + public Constraint[] getConstraints(Component child); + + public Component getChildAt(int x, int y); + + public boolean hasChild(Component component); + + public boolean remove(Component child); + + public void layoutChildren(); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/DraggableComponent.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/DraggableComponent.java new file mode 100644 index 000000000..9584751ec --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/DraggableComponent.java @@ -0,0 +1,8 @@ +package org.darkstorm.minecraft.gui.component; + +public interface DraggableComponent extends Component +{ + public boolean isDragging(); + + public void setDragging(boolean dragging); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/Frame.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Frame.java new file mode 100644 index 000000000..7b4599350 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Frame.java @@ -0,0 +1,30 @@ +package org.darkstorm.minecraft.gui.component; + +public interface Frame extends Container, DraggableComponent +{ + public String getTitle(); + + public void setTitle(String title); + + public boolean isPinned(); + + public void setPinned(boolean pinned); + + public boolean isPinnable(); + + public void setPinnable(boolean pinnable); + + public boolean isMinimized(); + + public void setMinimized(boolean minimized); + + public boolean isMinimizable(); + + public void setMinimizable(boolean minimizable); + + public void close(); + + public boolean isClosable(); + + public void setClosable(boolean closable); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/Label.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Label.java new file mode 100644 index 000000000..8092e1885 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Label.java @@ -0,0 +1,21 @@ +package org.darkstorm.minecraft.gui.component; + +public interface Label extends TextComponent +{ + public enum TextAlignment + { + CENTER, + LEFT, + RIGHT, + TOP, + BOTTOM + } + + public TextAlignment getHorizontalAlignment(); + + public TextAlignment getVerticalAlignment(); + + public void setHorizontalAlignment(TextAlignment alignment); + + public void setVerticalAlignment(TextAlignment alignment); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/Panel.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Panel.java new file mode 100644 index 000000000..1b3fade04 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Panel.java @@ -0,0 +1,4 @@ +package org.darkstorm.minecraft.gui.component; + +public interface Panel extends Container +{} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/ProgressBar.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/ProgressBar.java new file mode 100644 index 000000000..376126861 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/ProgressBar.java @@ -0,0 +1,8 @@ +package org.darkstorm.minecraft.gui.component; + +public interface ProgressBar extends Component, BoundedRangeComponent +{ + public boolean isIndeterminate(); + + public void setIndeterminate(boolean indeterminate); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/RadioButton.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/RadioButton.java new file mode 100644 index 000000000..b782711e7 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/RadioButton.java @@ -0,0 +1,4 @@ +package org.darkstorm.minecraft.gui.component; + +public interface RadioButton extends Button, SelectableComponent +{} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/SelectableComponent.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/SelectableComponent.java new file mode 100644 index 000000000..6e9c0758b --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/SelectableComponent.java @@ -0,0 +1,16 @@ +package org.darkstorm.minecraft.gui.component; + +import org.darkstorm.minecraft.gui.listener.SelectableComponentListener; + +public interface SelectableComponent extends Component +{ + public boolean isSelected(); + + public void setSelected(boolean selected); + + public void addSelectableComponentListener( + SelectableComponentListener listener); + + public void removeSelectableComponentListener( + SelectableComponentListener listener); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/Slider.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Slider.java new file mode 100644 index 000000000..a6e45c52d --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/Slider.java @@ -0,0 +1,18 @@ +package org.darkstorm.minecraft.gui.component; + +import org.darkstorm.minecraft.gui.listener.SliderListener; + +public interface Slider extends Component, TextComponent, BoundedRangeComponent +{ + public String getContentSuffix(); + + public boolean isValueChanging(); + + public void setContentSuffix(String suffix); + + public void setValueChanging(boolean changing); + + public void addSliderListener(SliderListener listener); + + public void removeSliderListener(SliderListener listener); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/TextComponent.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/TextComponent.java new file mode 100644 index 000000000..c2a23bbd2 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/TextComponent.java @@ -0,0 +1,8 @@ +package org.darkstorm.minecraft.gui.component; + +public interface TextComponent extends Component +{ + public String getText(); + + public void setText(String text); +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/basic/BasicButton.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/basic/BasicButton.java new file mode 100644 index 000000000..798aa3684 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/basic/BasicButton.java @@ -0,0 +1,78 @@ +package org.darkstorm.minecraft.gui.component.basic; + +import org.darkstorm.minecraft.gui.component.AbstractComponent; +import org.darkstorm.minecraft.gui.component.Button; +import org.darkstorm.minecraft.gui.component.ButtonGroup; +import org.darkstorm.minecraft.gui.listener.ButtonListener; +import org.darkstorm.minecraft.gui.listener.ComponentListener; + +public class BasicButton extends AbstractComponent implements Button +{ + protected String text = ""; + protected ButtonGroup group; + private String description; + + public BasicButton() + {} + + public BasicButton(String text, String description) + { + this.text = text; + this.description = description; + } + + @Override + public String getText() + { + return text; + } + + @Override + public void setText(String text) + { + this.text = text; + } + + @Override + public String getDescription() + { + return description; + } + + @Override + public void setDescription(String desccription) + { + description = desccription; + } + + @Override + public void press() + { + for(ComponentListener listener : getListeners()) + ((ButtonListener)listener).onButtonPress(this); + } + + @Override + public void addButtonListener(ButtonListener listener) + { + addListener(listener); + } + + @Override + public void removeButtonListener(ButtonListener listener) + { + removeListener(listener); + } + + @Override + public ButtonGroup getGroup() + { + return group; + } + + @Override + public void setGroup(ButtonGroup group) + { + this.group = group; + } +} diff --git a/Wurst Client/src/org/darkstorm/minecraft/gui/component/basic/BasicButtonGroup.java b/Wurst Client/src/org/darkstorm/minecraft/gui/component/basic/BasicButtonGroup.java new file mode 100644 index 000000000..05b2c3433 --- /dev/null +++ b/Wurst Client/src/org/darkstorm/minecraft/gui/component/basic/BasicButtonGroup.java @@ -0,0 +1,44 @@ +package org.darkstorm.minecraft.gui.component.basic; + +import java.util.ArrayList; +import java.util.List; + +import org.darkstorm.minecraft.gui.component.Button; +import org.darkstorm.minecraft.gui.component.ButtonGroup; + +public class BasicButtonGroup implements ButtonGroup +{ + private List