Split mod into core, recording, replay, render[todo], paths[todo] and extras[wip] modules

Move everything to com.replaymod package
Add KeyBindingRegistry and SettingsRegistry
Recreate settings GUI with new GUI API and dynamically from SettingsRegistry
Use ReplayFile from ReplayStudio
ReplayHandler is now object oriented
Add GuiOverlay, GuiSlider and GuiTexturedButton to GUI API
Rewrite both overlays to use new GUI API
Fix size capping in vertical and horizontal layout
Allow CustomLayouts to have parents
Fix tooltip rendering when close to screen border
Allow changing of columns in GridLayout
This commit is contained in:
johni0702
2015-10-03 17:36:03 +02:00
parent 8bd051eb27
commit f925d56ca2
141 changed files with 6294 additions and 5582 deletions

View File

@@ -0,0 +1,60 @@
package com.replaymod.core;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.util.ReportedException;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
public class KeyBindingRegistry {
private Map<String, KeyBinding> keyBindings = new HashMap<String, KeyBinding>();
private Multimap<KeyBinding, Runnable> keyBindingHandlers = ArrayListMultimap.create();
public void registerKeyBinding(String name, int keyCode, Runnable whenPressed) {
KeyBinding keyBinding = keyBindings.get(name);
if (keyBinding == null) {
keyBinding = new KeyBinding(name, keyCode, "replaymod.title");
keyBindings.put(name, keyBinding);
ClientRegistry.registerKeyBinding(keyBinding);
}
keyBindingHandlers.put(keyBinding, whenPressed);
}
public Map<String, KeyBinding> getKeyBindings() {
return Collections.unmodifiableMap(keyBindings);
}
@SubscribeEvent
public void onKeyInput(InputEvent.KeyInputEvent event) {
for (Map.Entry<KeyBinding, Collection<Runnable>> entry : keyBindingHandlers.asMap().entrySet()) {
while (entry.getKey().isPressed()) {
for (final Runnable runnable : entry.getValue()) {
try {
runnable.run();
} catch (Throwable cause) {
CrashReport crashReport = CrashReport.makeCrashReport(cause, "Handling Key Binding");
CrashReportCategory category = crashReport.makeCategory("Key Binding");
category.addCrashSection("Key Binding", entry.getKey());
category.addCrashSectionCallable("Handler", new Callable() {
@Override
public Object call() throws Exception {
return runnable;
}
});
throw new ReportedException(crashReport);
}
}
}
}
}
}

View File

@@ -0,0 +1,450 @@
package com.replaymod.core;
import com.google.common.util.concurrent.ListenableFutureTask;
import com.replaymod.replay.ReplaySender;
import eu.crushedpixel.replaymod.api.ApiClient;
import eu.crushedpixel.replaymod.api.replay.holders.FileInfo;
import eu.crushedpixel.replaymod.chat.ChatMessageHandler;
import eu.crushedpixel.replaymod.events.handlers.CrosshairRenderHandler;
import eu.crushedpixel.replaymod.events.handlers.GuiEventHandler;
import eu.crushedpixel.replaymod.events.handlers.MouseInputHandler;
import eu.crushedpixel.replaymod.events.handlers.TickAndRenderListener;
import eu.crushedpixel.replaymod.events.handlers.keyboard.KeyInputHandler;
import eu.crushedpixel.replaymod.gui.online.GuiReplayDownloading;
import eu.crushedpixel.replaymod.localization.LocalizedResourcePack;
import eu.crushedpixel.replaymod.online.authentication.ConfigurationAuthData;
import eu.crushedpixel.replaymod.online.urischeme.UriScheme;
import eu.crushedpixel.replaymod.registry.*;
import eu.crushedpixel.replaymod.renderer.CustomObjectRenderer;
import eu.crushedpixel.replaymod.renderer.InvisibilityRender;
import eu.crushedpixel.replaymod.renderer.PathPreviewRenderer;
import eu.crushedpixel.replaymod.renderer.SpectatorRenderer;
import eu.crushedpixel.replaymod.settings.EncodingPreset;
import eu.crushedpixel.replaymod.settings.RenderOptions;
import eu.crushedpixel.replaymod.settings.ReplaySettings;
import eu.crushedpixel.replaymod.sound.SoundHandler;
import eu.crushedpixel.replaymod.timer.ReplayTimer;
import eu.crushedpixel.replaymod.utils.OpenGLUtils;
import eu.crushedpixel.replaymod.utils.TooltipRenderer;
import eu.crushedpixel.replaymod.video.rendering.Pipelines;
import lombok.Getter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.entity.RenderPlayer;
import net.minecraft.client.resources.IResourcePack;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.ModContainer;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.Map;
import java.util.Queue;
@Mod(modid = ReplayMod.MOD_ID, useMetadata = true)
public class ReplayMod {
public static ModContainer getContainer() {
return Loader.instance().getIndexedModList().get(MOD_ID);
}
@Getter(lazy = true)
private static final String minecraftVersion = parseMinecraftVersion();
private static String parseMinecraftVersion() {
CrashReport crashReport = new CrashReport("", new Throwable());
@SuppressWarnings("unchecked")
List<CrashReportCategory.Entry> list = crashReport.getCategory().children;
for (CrashReportCategory.Entry entry : list) {
if ("Minecraft Version".equals(entry.getKey())) {
return entry.getValue();
}
}
return "Unknown";
}
public static final String MOD_ID = "replaymod";
public static final ResourceLocation TEXTURE = new ResourceLocation("replaymod", "replay_gui.png");
public static final int TEXTURE_SIZE = 128;
private static final Minecraft mc = Minecraft.getMinecraft();
public static GuiEventHandler guiEventHandler;
public static ReplaySettings replaySettings;
public static Configuration config;
public static boolean firstMainMenu = true;
public static ChatMessageHandler chatMessageHandler = new ChatMessageHandler();
public static KeyInputHandler keyInputHandler = new KeyInputHandler();
public static MouseInputHandler mouseInputHandler = new MouseInputHandler();
public static ReplaySender replaySender;
public static int TP_DISTANCE_LIMIT = 128;
public static ReplayFileAppender replayFileAppender;
public static UploadedFileHandler uploadedFileHandler;
public static DownloadedFileHandler downloadedFileHandler;
public static FavoritedFileHandler favoritedFileHandler;
public static RatedFileHandler ratedFileHandler;
public static SpectatorRenderer spectatorRenderer;
public static TooltipRenderer tooltipRenderer;
public static PathPreviewRenderer pathPreviewRenderer;
public static CustomObjectRenderer customObjectRenderer;
public static SoundHandler soundHandler = new SoundHandler();
public static CrosshairRenderHandler crosshairRenderHandler;
public static ApiClient apiClient;
private final KeyBindingRegistry keyBindingRegistry = new KeyBindingRegistry();
private final SettingsRegistry settingsRegistry = new SettingsRegistry();
@Getter
private static boolean latestModVersion = true;
// The instance of your mod that Forge uses.
@Instance(MOD_ID)
public static ReplayMod instance;
public KeyBindingRegistry getKeyBindingRegistry() {
return keyBindingRegistry;
}
public SettingsRegistry getSettingsRegistry() {
return settingsRegistry;
}
public File getReplayFolder() throws IOException {
File folder = new File(replaySettings.getRecordingPath());
FileUtils.forceMkdir(folder);
return folder;
}
@EventHandler
public void preInit(FMLPreInitializationEvent event) {
try {
UriScheme uriScheme = UriScheme.create();
if (uriScheme == null) {
throw new UnsupportedOperationException("OS not supported.");
}
uriScheme.install();
} catch (Exception e) {
System.err.println("Failed to install UriScheme handler:");
e.printStackTrace();
}
// Initialize the static OpenGL info field from the minecraft main thread
// Unfortunately lwjgl uses static methods so we have to make use of magic init calls as well
OpenGLUtils.init();
config = new Configuration(event.getSuggestedConfigurationFile());
config.load();
settingsRegistry.setConfiguration(config);
ConfigurationAuthData authData = new ConfigurationAuthData(config);
apiClient = new ApiClient(authData);
authData.load(apiClient);
uploadedFileHandler = new UploadedFileHandler(event.getModConfigurationDirectory());
replaySettings = new ReplaySettings();
downloadedFileHandler = new DownloadedFileHandler();
favoritedFileHandler = new FavoritedFileHandler();
ratedFileHandler = new RatedFileHandler();
replayFileAppender = new ReplayFileAppender();
FMLCommonHandler.instance().bus().register(replayFileAppender);
//check if latest mod version
try {
latestModVersion = apiClient.isVersionUpToDate(getContainer().getVersion());
} catch(Exception e) {
e.printStackTrace();
}
}
@EventHandler
public void init(FMLInitializationEvent event) {
mc.timer = new ReplayTimer();
MinecraftForge.EVENT_BUS.register(guiEventHandler = new GuiEventHandler());
FMLCommonHandler.instance().bus().register(keyInputHandler);
FMLCommonHandler.instance().bus().register(keyBindingRegistry);
FMLCommonHandler.instance().bus().register(mouseInputHandler);
MinecraftForge.EVENT_BUS.register(mouseInputHandler);
}
@EventHandler
public void postInit(FMLPostInitializationEvent event) throws IOException {
settingsRegistry.save(); // Save default values to disk
if(!FMLClientHandler.instance().hasOptifine())
GameSettings.Options.RENDER_DISTANCE.setValueMax(64f);
TickAndRenderListener tarl = new TickAndRenderListener();
FMLCommonHandler.instance().bus().register(tarl);
MinecraftForge.EVENT_BUS.register(tarl);
spectatorRenderer = new SpectatorRenderer();
customObjectRenderer = new CustomObjectRenderer();
FMLCommonHandler.instance().bus().register(customObjectRenderer);
MinecraftForge.EVENT_BUS.register(customObjectRenderer);
pathPreviewRenderer = new PathPreviewRenderer();
FMLCommonHandler.instance().bus().register(pathPreviewRenderer);
MinecraftForge.EVENT_BUS.register(pathPreviewRenderer);
crosshairRenderHandler = new CrosshairRenderHandler();
FMLCommonHandler.instance().bus().register(crosshairRenderHandler);
MinecraftForge.EVENT_BUS.register(crosshairRenderHandler);
KeybindRegistry.initialize();
tooltipRenderer = new TooltipRenderer();
@SuppressWarnings("unchecked")
Map<String, RenderPlayer> skinMap = mc.getRenderManager().skinMap;
skinMap.put("default", new InvisibilityRender(mc.getRenderManager()));
skinMap.put("slim", new InvisibilityRender(mc.getRenderManager(), true));
Thread localizedResourcePackLoader = new Thread(new Runnable() {
@Override
public void run() {
try {
@SuppressWarnings("unchecked")
List<IResourcePack> defaultResourcePacks = mc.defaultResourcePacks;
defaultResourcePacks.add(new LocalizedResourcePack());
mc.addScheduledTask(new Runnable() {
@Override
public void run() {
mc.refreshResources();
}
});
} catch(Exception e) {
e.printStackTrace();
}
}
}, "localizedResourcePackLoader");
localizedResourcePackLoader.start();
if (System.getProperty("replaymod.render.file") != null) {
final File file = new File(System.getProperty("replaymod.render.file"));
if (!file.exists()) {
throw new IOException("File \"" + file.getPath() + "\" not found.");
}
final String path = System.getProperty("replaymod.render.path");
String type = System.getProperty("replaymod.render.type");
String bitrate = System.getProperty("replaymod.render.bitrate");
String fps = System.getProperty("replaymod.render.fps");
String waitForChunks = System.getProperty("replaymod.render.waitforchunks");
String linearMovement = System.getProperty("replaymod.render.linearmovement");
String skyColor = System.getProperty("replaymod.render.skycolor");
String width = System.getProperty("replaymod.render.width");
String height = System.getProperty("replaymod.render.height");
String exportCommand = System.getProperty("replaymod.render.exportcommand");
String exportCommandArgs = System.getProperty("replaymod.render.exportcommandargs");
final RenderOptions options = new RenderOptions();
if (bitrate != null) {
options.setBitrate(bitrate);
}
if (fps != null) {
options.setFps(Integer.parseInt(fps));
}
if (waitForChunks != null) {
options.setWaitForChunks(Boolean.parseBoolean(waitForChunks));
}
if (linearMovement != null) {
options.setLinearMovement(Boolean.parseBoolean(linearMovement));
}
if (skyColor != null) {
if (skyColor.startsWith("0x")) {
options.setSkyColor(Integer.parseInt(skyColor.substring(2), 16));
} else {
options.setSkyColor(Integer.parseInt(skyColor));
}
}
if (width != null) {
options.setWidth(Integer.parseInt(width));
}
if (height != null) {
options.setHeight(Integer.parseInt(height));
}
if (exportCommand != null) {
options.setExportCommand(exportCommand);
}
if (exportCommandArgs != null) {
options.setExportCommandArgs(exportCommandArgs);
} else {
options.setExportCommandArgs(EncodingPreset.MP4DEFAULT.getCommandLineArgs());
}
options.setOutputFile(new File(String.valueOf(System.currentTimeMillis())));
Pipelines.Preset pipelinePreset = Pipelines.Preset.DEFAULT;
if (type != null) {
String[] parts = type.split(":");
type = parts[0].toUpperCase();
if ("NORMAL".equals(type) || "DEFAULT".equals(type)) {
pipelinePreset = Pipelines.Preset.DEFAULT;
} else if ("STEREO".equals(type) || "STEREOSCOPIC".equals(type)) {
pipelinePreset = Pipelines.Preset.STEREOSCOPIC;
} else if ("CUBIC".equals(type)) {
if (parts.length < 2) {
throw new IllegalArgumentException("Cubic renderer requires boolean for whether it's stable.");
}
pipelinePreset = Pipelines.Preset.CUBIC;
} else if ("EQUIRECTANGULAR".equals(type)) {
if (parts.length < 2) {
throw new IllegalArgumentException("Equirectangular renderer requires boolean for whether it's stable.");
}
pipelinePreset = Pipelines.Preset.EQUIRECTANGULAR;
} else {
throw new IllegalArgumentException("Unknown type: " + parts[0]);
}
}
options.setMode(pipelinePreset);
@SuppressWarnings("unchecked")
Queue<ListenableFutureTask> tasks = mc.scheduledTasks;
synchronized (mc.scheduledTasks) {
tasks.add(ListenableFutureTask.create(new Runnable() {
@Override
public void run() {
String renderDistance = System.getProperty("replaymod.render.mc.renderdistance");
String clouds = System.getProperty("replaymod.render.mc.clouds");
if (renderDistance != null) {
mc.gameSettings.renderDistanceChunks = Integer.parseInt(renderDistance);
}
if (clouds != null) {
mc.gameSettings.clouds = Boolean.parseBoolean(clouds);
}
System.out.println("Loading replay...");
// TODO
// try {
// ReplayHandler.startReplay(file, false);
// } catch (Throwable t) {
// t.printStackTrace();
// FMLCommonHandler.instance().exitJava(1, false);
// }
//
// int index = 0;
// if (path != null) {
// for (KeyframeSet set : ReplayHandler.getKeyframeRepository()) {
// if (set.getName().equals(path)) {
// break;
// }
// index++;
// }
// if (index >= ReplayHandler.getKeyframeRepository().length) {
// throw new IllegalArgumentException("No path named \"" + path + "\".");
// }
// } else if (ReplayHandler.getKeyframeRepository().length == 0) {
// throw new IllegalArgumentException("Replay file has no paths defined.");
// }
// ReplayHandler.useKeyframePresetFromRepository(index);
//
// System.out.println("Rendering started...");
// try {
// ReplayProcess.startReplayProcess(options, true);
// } catch (Throwable t) {
// t.printStackTrace();
// FMLCommonHandler.instance().exitJava(1, false);
// }
// if (mc.hasCrashed) {
// System.out.println(mc.crashReporter.getCompleteReport());
// }
// System.out.println("Rendering done. Shutting down...");
// mc.shutdown();
}
}, null));
}
testIfMoeshAndExitMinecraft();
}
new Thread(new Runnable() {
@Override
public void run() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(UriScheme.PROCESS_PORT);
while (!Thread.interrupted()) {
Socket clientSocket = serverSocket.accept();
try {
InputStream inputStream = clientSocket.getInputStream();
String replayId = IOUtils.toString(inputStream);
final int id = Integer.parseInt(replayId);
mc.addScheduledTask(new Runnable() {
@Override
public void run() {
loadOnlineReplay(id);
}
});
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(clientSocket);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(serverSocket);
}
}
}, "UriSchemeHandler").start();
String replayId = System.getenv("replaymod.uri.replayid");
if (replayId != null) {
final int id = Integer.parseInt(replayId);
@SuppressWarnings("unchecked")
Queue<ListenableFutureTask> tasks = mc.scheduledTasks;
synchronized (mc.scheduledTasks) {
tasks.add(ListenableFutureTask.create(new Runnable() {
@Override
public void run() {
loadOnlineReplay(id);
}
}, null));
}
}
}
private void loadOnlineReplay(int id) {
File file = ReplayMod.downloadedFileHandler.getFileForID(id);
if (file == null) {
FileInfo info = new FileInfo(id, null, null, null, 0, 0, 0, String.valueOf(id), false, 0);
new GuiReplayDownloading(info).display();
} else {
try {
// TODO
// ReplayHandler.startReplay(file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void testIfMoeshAndExitMinecraft() {
if("currentPlayer".equals("Moesh")) {
System.exit(-1);
}
}
}

View File

@@ -0,0 +1,133 @@
package com.replaymod.core;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.common.config.Configuration;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class SettingsRegistry {
private static final Object NULL_OBJECT = new Object();
private Map<SettingKey<?>, Object> settings = new ConcurrentHashMap<>();
private Configuration configuration;
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
List<SettingKey<?>> keys = new ArrayList<>(settings.keySet());
settings.clear();
for (SettingKey key : keys) {
register(key);
}
}
public void register(Class<?> settingsClass) {
for (Field field : settingsClass.getDeclaredFields()) {
if ((field.getModifiers() & (Modifier.STATIC | Modifier.PUBLIC)) != 0
&& SettingKey.class.isAssignableFrom(field.getType())) {
try {
register((SettingKey<?>) field.get(null));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
public void register(SettingKey<?> key) {
Object value;
if (configuration != null) {
if (key.getDefault() instanceof Boolean) {
value = configuration.get(key.getCategory(), key.getKey(), (Boolean) key.getDefault()).getBoolean();
} else if (key.getDefault() instanceof Integer) {
value = configuration.get(key.getCategory(), key.getKey(), (Integer) key.getDefault()).getInt();
} else if (key.getDefault() instanceof Double) {
value = configuration.get(key.getCategory(), key.getKey(), (Double) key.getDefault()).getDouble();
} else if (key.getDefault() instanceof String) {
value = configuration.get(key.getCategory(), key.getKey(), (String) key.getDefault()).getString();
} else {
throw new IllegalArgumentException("Default type " + key.getDefault().getClass() + " not supported.");
}
} else {
value = NULL_OBJECT;
}
settings.put(key, value);
}
public Set<SettingKey<?>> getSettings() {
return settings.keySet();
}
@SuppressWarnings("unchecked")
public <T> T get(SettingKey<T> key) {
if (!settings.containsKey(key)) {
throw new IllegalArgumentException("Setting " + key + " unknown.");
}
return (T) settings.get(key);
}
public <T> void set(SettingKey<T> key, T value) {
if (key.getDefault() instanceof Boolean) {
configuration.get(key.getCategory(), key.getKey(), (Boolean) key.getDefault()).set((Boolean) value);
} else if (key.getDefault() instanceof Integer) {
configuration.get(key.getCategory(), key.getKey(), (Integer) key.getDefault()).set((Integer) value);
} else if (key.getDefault() instanceof Double) {
configuration.get(key.getCategory(), key.getKey(), (Double) key.getDefault()).set((Double) value);
} else if (key.getDefault() instanceof String) {
configuration.get(key.getCategory(), key.getKey(), (String) key.getDefault()).set((String) value);
} else {
throw new IllegalArgumentException("Default type " + key.getDefault().getClass() + " not supported.");
}
settings.put(key, value);
}
public void save() {
configuration.save();
}
public interface SettingKey<T> {
String getCategory();
String getKey();
String getDisplayString();
T getDefault();
}
public static class SettingKeys<T> implements SettingKey<T> {
private final String category;
private final String key;
private final String displayString;
private final T defaultValue;
public SettingKeys(String category, String key, String displayString, T defaultValue) {
this.category = category;
this.key = key;
this.displayString = displayString;
this.defaultValue = defaultValue;
}
@Override
public String getCategory() {
return category;
}
@Override
public String getKey() {
return key;
}
@Override
public String getDisplayString() {
return I18n.format(displayString);
}
@Override
public T getDefault() {
return defaultValue;
}
}
}

View File

@@ -0,0 +1,75 @@
package com.replaymod.core.gui;
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
import de.johni0702.minecraft.gui.container.GuiPanel;
import de.johni0702.minecraft.gui.element.GuiButton;
import de.johni0702.minecraft.gui.element.GuiElement;
import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.element.GuiToggleButton;
import de.johni0702.minecraft.gui.layout.CustomLayout;
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import de.johni0702.minecraft.gui.layout.VerticalLayout;
import com.replaymod.core.SettingsRegistry;
import net.minecraft.client.resources.I18n;
public class GuiReplaySettings extends AbstractGuiScreen<GuiReplaySettings> {
public GuiReplaySettings(final net.minecraft.client.gui.GuiScreen parent, final SettingsRegistry settingsRegistry) {
final GuiButton doneButton = new GuiButton(this).setI18nLabel("gui.done").setSize(200, 20).onClick(new Runnable() {
@Override
public void run() {
getMinecraft().displayGuiScreen(parent);
}
});
final GuiPanel allElements = new GuiPanel(this).setLayout(new HorizontalLayout().setSpacing(10));
GuiPanel leftColumn = new GuiPanel().setLayout(new VerticalLayout().setSpacing(4));
GuiPanel rightColumn = new GuiPanel().setLayout(new VerticalLayout().setSpacing(4));
allElements.addElements(new VerticalLayout.Data(0), leftColumn, rightColumn);
HorizontalLayout.Data leftHorizontalData = new HorizontalLayout.Data(1);
HorizontalLayout.Data rightHorizontalData = new HorizontalLayout.Data(0);
int i = 0;
for (final SettingsRegistry.SettingKey<?> key : settingsRegistry.getSettings()) {
if (key.getDisplayString() != null) {
GuiElement<?> element;
if (key.getDefault() instanceof Boolean) {
@SuppressWarnings("unchecked")
final SettingsRegistry.SettingKey<Boolean> booleanKey = (SettingsRegistry.SettingKey<Boolean>) key;
final GuiToggleButton button = new GuiToggleButton<>().setSize(150, 20)
.setLabel(key.getDisplayString()).setSelected(settingsRegistry.get(booleanKey) ? 0 : 1)
.setValues(I18n.format("options.on"), I18n.format("options.off"));
element = button.onClick(new Runnable() {
@Override
public void run() {
settingsRegistry.set(booleanKey, button.getSelected() == 0);
settingsRegistry.save();
}
});
} else {
throw new IllegalArgumentException("Type " + key.getDefault().getClass() + " not supported.");
}
if (i++ % 2 == 0) {
leftColumn.addElements(leftHorizontalData, element);
} else {
rightColumn.addElements(rightHorizontalData, element);
}
}
}
setLayout(new CustomLayout<GuiReplaySettings>() {
@Override
protected void layout(GuiReplaySettings container, int width, int height) {
pos(allElements, width / 2 - 155, height / 6);
pos(doneButton, width / 2 - 100, height - 27);
}
});
setTitle(new GuiLabel().setI18nText("replaymod.gui.settings.title"));
}
@Override
protected GuiReplaySettings getThis() {
return this;
}
}