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,182 @@
package com.replaymod.replay.gui.overlay;
import de.johni0702.replaystudio.data.Marker;
import com.replaymod.core.ReplayMod;
import eu.crushedpixel.replaymod.gui.elements.timelines.GuiTimeline;
import eu.crushedpixel.replaymod.holders.AdvancedPosition;
import com.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.utils.MouseUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
import org.lwjgl.util.Point;
import java.awt.*;
public class GuiMarkerTimeline extends GuiTimeline {
private static final int KEYFRAME_MARKER_X = 109;
private static final int KEYFRAME_MARKER_Y = 20;
private final ReplayHandler replayHandler;
private Marker selectedMarker;
private Marker clickedMarker;
private long clickTime;
private boolean dragging;
public GuiMarkerTimeline(ReplayHandler replayHandler, int positionX, int positionY, int width, int height) {
super(positionX, positionY, width, height);
this.replayHandler = replayHandler;
this.showMarkers = false;
}
@Override
public boolean mouseClick(Minecraft mc, int mouseX, int mouseY, int button) {
if(!enabled) return false;
long time = getTimeAt(mouseX, mouseY);
if(time == -1) {
return false;
}
int tolerance = (int) (2 * Math.round(zoom * timelineLength / width));
Marker closest = null;
if(mouseY >= positionY + BORDER_TOP + 10) {
long distance = tolerance;
for (Marker m : replayHandler.getMarkers()) {
long d = Math.abs(m.getTime() - time);
if (d <= distance) {
closest = m;
distance = d;
}
}
}
//left mouse button
if(button == 0) {
if(closest == null) { //if no keyframe clicked, jump in time
replayHandler.doJump((int) getTimeAt(mouseX, mouseY), true);
} else {
selectedMarker = closest;
// If we clicked on a key frame, then continue monitoring the mouse for movements
long currentTime = System.currentTimeMillis();
if(currentTime - clickTime < 500) { // if double clicked then open GUI instead
// mc.displayGuiScreen(GuiEditKeyframe.create(closest));
// TODO Edit Gui
this.clickedMarker = null;
} else {
this.clickedMarker = closest;
this.dragging = false;
}
this.clickTime = currentTime;
}
} else if(button == 1) {
if(closest != null) {
//Jump to clicked Marker Keyframe (explicitly force to jump to this position)
replayHandler.setTargetPosition(new AdvancedPosition(
closest.getX(), closest.getY(), closest.getZ(),
closest.getPitch(), closest.getYaw(), closest.getRoll()
));
//perform the jump, telling the Overlay not to override the last position value
replayHandler.doJump(closest.getTime(), false);
}
}
return isHovering(mouseX, mouseY);
}
@Override
public void mouseDrag(Minecraft mc, int mouseX, int mouseY, int button) {
if(!enabled) return;
long time = getTimeAt(mouseX, mouseY);
if (time != -1) {
if (clickedMarker != null) {
int tolerance = (int) (2 * Math.round(zoom * timelineLength / width));
if (dragging || Math.abs(clickedMarker.getTime() - time) > tolerance) {
clickedMarker.setTime((int) time);
dragging = true;
}
}
}
}
@Override
public void mouseRelease(Minecraft mc, int mouseX, int mouseY, int button) {
mouseDrag(mc, mouseX, mouseY, button);
clickedMarker = null;
if (dragging) {
replayHandler.saveMarkers();
dragging = false;
}
}
@Override
public void draw(Minecraft mc, int mouseX, int mouseY) {
super.draw(mc, mouseX, mouseY);
int bodyWidth = width - BORDER_LEFT - BORDER_RIGHT;
long leftTime = Math.round(timeStart * timelineLength);
long rightTime = Math.round((timeStart + zoom) * timelineLength);
double segmentLength = timelineLength * zoom;
drawTimelineCursor(leftTime, rightTime, bodyWidth);
//Draw Keyframe logos
for (Marker marker : replayHandler.getMarkers()) {
drawMarker(marker, bodyWidth, leftTime, rightTime, segmentLength);
}
}
private int getMarkerX(int timestamp, long leftTime, int bodyWidth, double segmentLength) {
long positionInSegment = timestamp - leftTime;
double fractionOfSegment = positionInSegment / segmentLength;
return (int) (positionX + BORDER_LEFT + fractionOfSegment * bodyWidth);
}
@Override
public void drawOverlay(Minecraft mc, int mouseX, int mouseY) {
boolean drawn = false;
int bodyWidth = width - BORDER_LEFT - BORDER_RIGHT;
long leftTime = Math.round(timeStart * timelineLength);
double segmentLength = timelineLength * zoom;
for (Marker marker : replayHandler.getMarkers()) {
int markerX = getMarkerX(marker.getTime(), leftTime, bodyWidth, segmentLength);
if(MouseUtils.isMouseWithinBounds(markerX - 2, this.positionY + BORDER_TOP + 10 + 1, 5, 5)) {
Point mouse = MouseUtils.getMousePos();
String markerName = marker.getName();
if(markerName == null || markerName.isEmpty()) markerName = I18n.format("replaymod.gui.ingame.unnamedmarker");
ReplayMod.tooltipRenderer.drawTooltip(mouse.getX(), mouse.getY(), markerName, null, Color.WHITE);
drawn = true;
}
}
if(!drawn) {
super.drawOverlay(mc, mouseX, mouseY);
}
}
private void drawMarker(Marker marker, int bodyWidth, long leftTime, long rightTime, double segmentLength) {
if (marker.getTime() <= rightTime && marker.getTime() >= leftTime) {
int textureX = KEYFRAME_MARKER_X;
int textureY = KEYFRAME_MARKER_Y;
int y = positionY+10;
int keyframeX = getMarkerX(marker.getTime(), leftTime, bodyWidth, segmentLength);
if (selectedMarker == marker) {
textureX += 5;
}
rect(keyframeX - 2, y + BORDER_TOP, textureX, textureY, 5, 5);
}
}
}

View File

@@ -0,0 +1,140 @@
package com.replaymod.replay.gui.overlay;
import com.replaymod.core.ReplayMod;
import com.replaymod.replay.ReplayHandler;
import com.replaymod.replay.ReplaySender;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
import de.johni0702.minecraft.gui.container.AbstractGuiOverlay;
import de.johni0702.minecraft.gui.container.GuiPanel;
import de.johni0702.minecraft.gui.element.GuiSlider;
import de.johni0702.minecraft.gui.element.GuiTexturedButton;
import de.johni0702.minecraft.gui.element.advanced.GuiTimeline;
import de.johni0702.minecraft.gui.element.advanced.IGuiTimeline;
import de.johni0702.minecraft.gui.layout.CustomLayout;
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.GameSettings;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import org.lwjgl.util.ReadableDimension;
import org.lwjgl.util.ReadablePoint;
import org.lwjgl.util.WritablePoint;
import static com.replaymod.core.ReplayMod.TEXTURE_SIZE;
public class GuiReplayOverlay extends AbstractGuiOverlay<GuiReplayOverlay> {
private final ReplayHandler replayHandler;
public final GuiPanel topPanel = new GuiPanel(this)
.setLayout(new HorizontalLayout(HorizontalLayout.Alignment.LEFT).setSpacing(5));
public final GuiTexturedButton playPauseButton = new GuiTexturedButton().setSize(20, 20)
.setTexture(ReplayMod.TEXTURE, TEXTURE_SIZE);
public final GuiSlider speedSlider = new GuiSlider().setSize(100, 20).setSteps(37); // 0.0 is not included
public final GuiTimeline timeline = new GuiTimeline(){
@Override
public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) {
setCursorPosition(replayHandler.getReplaySender().currentTimeStamp());
super.draw(renderer, size, renderInfo);
}
}.setSize(Integer.MAX_VALUE, 20);
public GuiReplayOverlay(final ReplayHandler replayHandler) {
this.replayHandler = replayHandler;
topPanel.addElements(null, playPauseButton, speedSlider, timeline);
setLayout(new CustomLayout<GuiReplayOverlay>() {
@Override
protected void layout(GuiReplayOverlay container, int width, int height) {
pos(topPanel, 10, 10);
size(topPanel, width - 20, 20);
}
});
playPauseButton.setTexturePosH(new ReadablePoint() {
@Override
public int getX() {
return 0;
}
@Override
public int getY() {
return replayHandler.getReplaySender().paused() ? 0 : 20;
}
@Override
public void getLocation(WritablePoint dest) {
dest.setLocation(getX(), getY());
}
}).onClick(new Runnable() {
@Override
public void run() {
ReplaySender replaySender = replayHandler.getReplaySender();
// If currently paused
if (replaySender.paused()) {
// then play
replaySender.setReplaySpeed(getSpeed());
} else {
// else pause
replaySender.setReplaySpeed(0);
}
}
});
speedSlider.onValueChanged(new Runnable() {
@Override
public void run() {
double speed = getSpeed();
speedSlider.setText(I18n.format("replaymod.gui.speed") + ": " + speed + "x");
ReplaySender replaySender = replayHandler.getReplaySender();
if (!replaySender.paused()) {
replaySender.setReplaySpeed(speed);
}
}
}).setValue(9);
timeline.onClick(new IGuiTimeline.OnClick() {
@Override
public void run(int time) {
replayHandler.doJump(time, true);
}
}).setLength(replayHandler.getReplaySender().replayLength());
}
private double getSpeed() {
int value = speedSlider.getValue() + 1;
if (value <= 9) {
return value / 10d;
} else {
return 1 + (0.25d * (value - 10));
}
}
@Override
public void setVisible(boolean visible) {
if (isVisible() != visible) {
if (visible) {
FMLCommonHandler.instance().bus().register(this);
} else {
FMLCommonHandler.instance().bus().unregister(this);
}
}
super.setVisible(visible);
}
@SubscribeEvent
public void onKeyInput(InputEvent.KeyInputEvent event) {
GameSettings gameSettings = getMinecraft().gameSettings;
while (gameSettings.keyBindChat.isPressed() || gameSettings.keyBindCommand.isPressed()) {
if (!isMouseVisible()) {
setMouseVisible(true);
}
}
}
@Override
protected GuiReplayOverlay getThis() {
return this;
}
}