Cleanup, relocate and split up GuiReplayOverlay
Merge gui resources into one texture
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
package eu.crushedpixel.replaymod.gui.elements;
|
||||
|
||||
import eu.crushedpixel.replaymod.gui.GuiEditKeyframe;
|
||||
import eu.crushedpixel.replaymod.holders.Keyframe;
|
||||
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
|
||||
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public class GuiKeyframeTimeline extends GuiTimeline {
|
||||
private static final int KEYFRAME_PLACE_X = 74;
|
||||
private static final int KEYFRAME_PLACE_Y = 20;
|
||||
private static final int KEYFRAME_TIME_X = 74;
|
||||
private static final int KEYFRAME_TIME_Y = 25;
|
||||
|
||||
private Keyframe clickedKeyFrame;
|
||||
private long clickTime;
|
||||
private boolean dragging;
|
||||
|
||||
public GuiKeyframeTimeline(int positionX, int positionY, int width) {
|
||||
super(positionX, positionY, width);
|
||||
showMarkers = true;
|
||||
}
|
||||
|
||||
public void mouseClicked(Minecraft mc, int mouseX, int mouseY) {
|
||||
long time = getTimeAt(mouseX, mouseY);
|
||||
if (time == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int tolerance = (int) (2 * Math.round(zoom * timelineLength / width));
|
||||
|
||||
Keyframe closest;
|
||||
if (mouseY >= positionY + BORDER_TOP + 5) {
|
||||
closest = ReplayHandler.getClosestTimeKeyframeForRealTime((int) time, tolerance);
|
||||
} else if (mouseY >= positionY + BORDER_TOP) {
|
||||
closest = ReplayHandler.getClosestPlaceKeyframeForRealTime((int) time, tolerance);
|
||||
} else {
|
||||
closest = null;
|
||||
}
|
||||
|
||||
ReplayHandler.selectKeyframe(closest); //can be null, deselects keyframe
|
||||
|
||||
// If we clicked on a key frame, then continue monitoring the mouse for movements
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (closest != null) {
|
||||
if (currentTime - clickTime < 500) { // if double clicked then open GUI instead
|
||||
mc.displayGuiScreen(new GuiEditKeyframe(closest));
|
||||
this.clickedKeyFrame = null;
|
||||
} else {
|
||||
this.clickedKeyFrame = closest;
|
||||
this.dragging = false;
|
||||
}
|
||||
} else { // If we didn't then just update the cursor
|
||||
ReplayHandler.setRealTimelineCursor((int) time);
|
||||
this.dragging = true;
|
||||
}
|
||||
this.clickTime = currentTime;
|
||||
}
|
||||
|
||||
public void mouseDrag(int mouseX, int mouseY) {
|
||||
long time = getTimeAt(mouseX, mouseY);
|
||||
if (time != -1) {
|
||||
if (clickedKeyFrame != null) {
|
||||
int tolerance = (int) (2 * Math.round(zoom * timelineLength / width));
|
||||
|
||||
if (dragging || Math.abs(clickedKeyFrame.getRealTimestamp() - time) > tolerance) {
|
||||
clickedKeyFrame.setRealTimestamp((int) time);
|
||||
ReplayHandler.sortKeyframes();
|
||||
dragging = true;
|
||||
}
|
||||
} else if (dragging) {
|
||||
ReplayHandler.setRealTimelineCursor((int) time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseRelease(int mouseX, int mouseY) {
|
||||
mouseDrag(mouseX, mouseY);
|
||||
clickedKeyFrame = null;
|
||||
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;
|
||||
|
||||
//Draw Keyframe logos
|
||||
for(Keyframe kf : ReplayHandler.getKeyframes()) {
|
||||
if (kf.getRealTimestamp() <= rightTime && kf.getRealTimestamp() >= leftTime) {
|
||||
int textureX;
|
||||
int textureY;
|
||||
int y = positionY;
|
||||
if (kf instanceof PositionKeyframe) {
|
||||
textureX = KEYFRAME_PLACE_X;
|
||||
textureY = KEYFRAME_PLACE_Y;
|
||||
y += 0;
|
||||
} else if (kf instanceof TimeKeyframe) {
|
||||
textureX = KEYFRAME_TIME_X;
|
||||
textureY = KEYFRAME_TIME_Y;
|
||||
y += 5;
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unknown keyframe type: " + kf.getClass());
|
||||
}
|
||||
|
||||
if (ReplayHandler.isSelected(kf)) {
|
||||
textureX += 5;
|
||||
}
|
||||
|
||||
long positionInSegment = kf.getRealTimestamp() - leftTime;
|
||||
double fractionOfSegment = positionInSegment / segmentLength;
|
||||
int x = (int) (positionX + BORDER_LEFT + fractionOfSegment * bodyWidth);
|
||||
|
||||
rect(x - 2, y + BORDER_TOP, textureX, textureY, 5, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package eu.crushedpixel.replaymod.gui.elements;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
|
||||
import static eu.crushedpixel.replaymod.gui.overlay.GuiReplayOverlay.TEXTURE_SIZE;
|
||||
import static eu.crushedpixel.replaymod.gui.overlay.GuiReplayOverlay.replay_gui;
|
||||
import static org.lwjgl.opengl.GL11.GL_BLEND;
|
||||
import static org.lwjgl.opengl.GL11.glEnable;
|
||||
|
||||
public class GuiScrollbar extends Gui {
|
||||
|
||||
protected static final int BORDER_LEFT = 1;
|
||||
protected static final int BORDER_RIGHT = 2;
|
||||
protected static final int BORDER_TOP = 1;
|
||||
|
||||
protected static final int BACKGROUND_WIDTH = 64;
|
||||
protected static final int BACKGROUND_HEIGHT = 9;
|
||||
protected static final int BACKGROUND_BODY_WIDTH = BACKGROUND_WIDTH - BORDER_LEFT - BORDER_RIGHT;
|
||||
protected static final int BACKGROUND_TEXTURE_X = 64;
|
||||
protected static final int BACKGROUND_TEXTURE_Y = 97;
|
||||
|
||||
protected static final int SLIDER_WIDTH = 62;
|
||||
protected static final int SLIDER_HEIGHT = 7;
|
||||
protected static final int SLIDER_TEXTURE_X = 64;
|
||||
protected static final int SLIDER_TEXTURE_Y = 90;
|
||||
protected static final int SLIDER_BORDER_LEFT = 1;
|
||||
protected static final int SLIDER_BORDER_RIGHT = 2;
|
||||
protected static final int SLIDER_BODY_WIDTH = SLIDER_WIDTH - SLIDER_BORDER_LEFT - SLIDER_BORDER_RIGHT;
|
||||
|
||||
/**
|
||||
* Current position of the left end of the slider. Must be between 0 and 1 - {@link #size} (inclusive).
|
||||
*/
|
||||
public double sliderPosition;
|
||||
|
||||
/**
|
||||
* Size of the slider. Should be between 0 (exclusive) and 1 (inclusive)
|
||||
*/
|
||||
public double size = 1;
|
||||
|
||||
protected final int positionX;
|
||||
protected final int positionY;
|
||||
protected final int width;
|
||||
|
||||
private int draggingStart;
|
||||
private double draggingStartPosition;
|
||||
|
||||
public GuiScrollbar(int positionX, int positionY, int width) {
|
||||
this.positionX = positionX;
|
||||
this.positionY = positionY;
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
private int getSliderOffsetX() {
|
||||
return (int) Math.round((width - BORDER_LEFT - BORDER_RIGHT) * sliderPosition) + BORDER_LEFT;
|
||||
}
|
||||
|
||||
public boolean startDragging(int mouseX, int mouseY) {
|
||||
int offsetX = getSliderOffsetX();
|
||||
int minX = positionX + offsetX;
|
||||
int maxX = positionX + offsetX + (int) (width * size);
|
||||
int minY = positionY + BORDER_TOP;
|
||||
int maxY = minY + SLIDER_HEIGHT;
|
||||
if (mouseX >= minX && mouseY >= minY && mouseX < maxX && mouseY < maxY) {
|
||||
draggingStart = mouseX;
|
||||
draggingStartPosition = sliderPosition;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void doDragging(int mouseX) {
|
||||
if (draggingStart != -1) {
|
||||
double delta = (double) (mouseX - draggingStart) / (width - BORDER_LEFT - BORDER_RIGHT);
|
||||
sliderPosition = Math.max(0, Math.min(1 - size, draggingStartPosition + delta));
|
||||
}
|
||||
}
|
||||
|
||||
public void endDragging(int mouseX) {
|
||||
doDragging(mouseX);
|
||||
draggingStart = -1;
|
||||
}
|
||||
|
||||
public void draw(Minecraft mc) {
|
||||
GlStateManager.resetColor();
|
||||
mc.renderEngine.bindTexture(replay_gui);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
// Background
|
||||
{
|
||||
// We have to increase the border size as there is one pixel row which is part of the border while drawing
|
||||
// but isn't during position calculations
|
||||
int BORDER_LEFT = GuiScrollbar.BORDER_LEFT + 1;
|
||||
int BACKGROUND_BODY_WIDTH = GuiScrollbar.BACKGROUND_BODY_WIDTH - 1;
|
||||
|
||||
int bodyLeft = positionX + BORDER_LEFT;
|
||||
int bodyRight = positionX + width - BORDER_RIGHT;
|
||||
|
||||
// Left border
|
||||
rect(positionX, positionY, BACKGROUND_TEXTURE_X, BACKGROUND_TEXTURE_Y, BORDER_LEFT, BACKGROUND_HEIGHT);
|
||||
// Body
|
||||
for (int i = bodyLeft; i < bodyRight; i += BACKGROUND_BODY_WIDTH) {
|
||||
rect(i, positionY, BACKGROUND_TEXTURE_X + BORDER_LEFT, BACKGROUND_TEXTURE_Y,
|
||||
Math.min(BACKGROUND_BODY_WIDTH, bodyRight - i), BACKGROUND_HEIGHT);
|
||||
}
|
||||
// Right border
|
||||
rect(bodyRight, positionY, BACKGROUND_TEXTURE_X + BACKGROUND_WIDTH - BORDER_RIGHT,
|
||||
BACKGROUND_TEXTURE_Y, BORDER_RIGHT, BACKGROUND_HEIGHT);
|
||||
}
|
||||
|
||||
// The slider itself
|
||||
{
|
||||
int positionX = this.positionX + getSliderOffsetX();
|
||||
int positionY = this.positionY + BORDER_TOP;
|
||||
|
||||
int backgroundBodyWidth = width - BORDER_LEFT - BORDER_RIGHT;
|
||||
int bodyLeft = positionX + SLIDER_BORDER_LEFT;
|
||||
int bodyRight = positionX + (int) Math.round(backgroundBodyWidth * size) - SLIDER_BORDER_RIGHT;
|
||||
|
||||
// Left border
|
||||
rect(positionX, positionY, SLIDER_TEXTURE_X, SLIDER_TEXTURE_Y, SLIDER_BORDER_LEFT, SLIDER_HEIGHT);
|
||||
// Body
|
||||
for (int i = bodyLeft; i < bodyRight; i += SLIDER_BODY_WIDTH) {
|
||||
rect(i, positionY, SLIDER_TEXTURE_X + SLIDER_BORDER_LEFT, SLIDER_TEXTURE_Y,
|
||||
Math.min(SLIDER_BODY_WIDTH, bodyRight - i), SLIDER_HEIGHT);
|
||||
}
|
||||
// Right border
|
||||
rect(bodyRight, positionY, SLIDER_TEXTURE_X + SLIDER_WIDTH - SLIDER_BORDER_RIGHT,
|
||||
SLIDER_TEXTURE_Y, SLIDER_BORDER_RIGHT, SLIDER_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
protected void rect(int x, int y, int u, int v, int width, int height) {
|
||||
GlStateManager.resetColor();
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(replay_gui);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
drawModalRectWithCustomSizedTexture(x, y, u, v, width, height, TEXTURE_SIZE, TEXTURE_SIZE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package eu.crushedpixel.replaymod.gui.elements;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class GuiTexturedButton extends GuiButton {
|
||||
private final ResourceLocation texture;
|
||||
private final int u, v;
|
||||
private final int textureWidth, textureHeight;
|
||||
public GuiTexturedButton(int buttonId, int x, int y, int width, int height, ResourceLocation texture,
|
||||
int u, int v, int textureWidth, int textureHeight) {
|
||||
super(buttonId, x, y, width, height, "");
|
||||
this.texture = texture;
|
||||
this.u = u;
|
||||
this.v = v;
|
||||
this.textureWidth = textureWidth;
|
||||
this.textureHeight = textureHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawButton(Minecraft mc, int mouseX, int mouseY) {
|
||||
if (visible) {
|
||||
hovered = mouseX >= xPosition
|
||||
&& mouseY >= yPosition
|
||||
&& mouseX < xPosition + width
|
||||
&& mouseY < yPosition + height;
|
||||
|
||||
mc.renderEngine.bindTexture(texture);
|
||||
|
||||
GlStateManager.color(1, 1, 1);
|
||||
int u = this.u + (hovered ? width : 0);
|
||||
Gui.drawModalRectWithCustomSizedTexture(xPosition, yPosition, u, v, width, height, textureWidth, textureHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package eu.crushedpixel.replaymod.gui.elements;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
|
||||
import static eu.crushedpixel.replaymod.gui.overlay.GuiReplayOverlay.TEXTURE_SIZE;
|
||||
import static eu.crushedpixel.replaymod.gui.overlay.GuiReplayOverlay.replay_gui;
|
||||
import static org.lwjgl.opengl.GL11.GL_BLEND;
|
||||
import static org.lwjgl.opengl.GL11.glEnable;
|
||||
|
||||
public class GuiTimeline extends Gui {
|
||||
|
||||
protected static final int TEXTURE_WIDTH = 64;
|
||||
protected static final int BORDER_TOP = 4;
|
||||
protected static final int BORDER_BOTTOM = 3;
|
||||
|
||||
protected static final int HEIGHT = 22;
|
||||
protected static final int TEXTURE_X = 64;
|
||||
protected static final int TEXTURE_Y = 106;
|
||||
|
||||
protected static final int BORDER_LEFT = 4;
|
||||
protected static final int BORDER_RIGHT = 4;
|
||||
protected static final int BODY_WIDTH = TEXTURE_WIDTH - BORDER_LEFT - BORDER_RIGHT;
|
||||
|
||||
/**
|
||||
* Current position of the cursor. Should normally be between 0 and {@link #timelineLength}.
|
||||
*/
|
||||
public int cursorPosition;
|
||||
|
||||
/**
|
||||
* Total length of the timeline.
|
||||
*/
|
||||
public int timelineLength;
|
||||
|
||||
/**
|
||||
* The time at the left border of this timeline (fraction of the total length).
|
||||
*/
|
||||
public double timeStart;
|
||||
|
||||
/**
|
||||
* Zoom of this timeline. 1/10 allows the user to see 1/10 of the total length.
|
||||
*/
|
||||
public double zoom = 1;
|
||||
|
||||
/**
|
||||
* Whether to draw markers on the timeline in regular time intervals.
|
||||
* This draws the time at big markers above the timeline. Therefore extra space in negative y direction
|
||||
* should be kept empty if markers are desired.
|
||||
*/
|
||||
public boolean showMarkers;
|
||||
|
||||
protected final int positionX;
|
||||
protected final int positionY;
|
||||
protected final int width;
|
||||
|
||||
public GuiTimeline(int positionX, int positionY, int width) {
|
||||
this.positionX = positionX;
|
||||
this.positionY = positionY;
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time which the mouse is at.
|
||||
* @param mouseX X coordinate of the mouse
|
||||
* @param mouseY Y coordinate of the mouse
|
||||
* @return The time or -1 if the mouse isn't on the timeline
|
||||
*/
|
||||
public long getTimeAt(int mouseX, int mouseY) {
|
||||
int left = positionX + BORDER_LEFT;
|
||||
int right = positionX + width - BORDER_RIGHT;
|
||||
int bodyWidth = width - BORDER_LEFT - BORDER_RIGHT;
|
||||
if (mouseX >= left && mouseX <= right && mouseY >= positionY && mouseY <= positionY + HEIGHT) {
|
||||
double segmentLength = timelineLength * zoom;
|
||||
double segmentTime = segmentLength * (mouseX - left) / bodyWidth;
|
||||
return Math.round(timeStart * timelineLength + segmentTime);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(Minecraft mc, int mouseX, int mouseY) {
|
||||
int bodyLeft = positionX + BORDER_LEFT;
|
||||
int bodyRight = positionX + width - BORDER_RIGHT;
|
||||
int bodyWidth = width - BORDER_LEFT - BORDER_RIGHT;
|
||||
|
||||
{
|
||||
// We have to increase the border size as there is one pixel row which is part of the border while drawing
|
||||
// but isn't during position calculations
|
||||
int BORDER_LEFT = GuiTimeline.BORDER_LEFT + 1;
|
||||
int BODY_WIDTH = GuiTimeline.BODY_WIDTH - 1;
|
||||
|
||||
// Left border
|
||||
rect(positionX, positionY, TEXTURE_X, TEXTURE_Y, BORDER_LEFT, HEIGHT);
|
||||
// Body
|
||||
for (int i = bodyLeft; i < bodyRight; i += BODY_WIDTH) {
|
||||
rect(i, positionY, TEXTURE_X + BORDER_LEFT, TEXTURE_Y, Math.min(BODY_WIDTH, bodyRight - i), HEIGHT);
|
||||
}
|
||||
// Right border
|
||||
rect(bodyRight, positionY, TEXTURE_X + BORDER_LEFT + BODY_WIDTH, TEXTURE_Y, BORDER_RIGHT, HEIGHT);
|
||||
}
|
||||
|
||||
long leftTime = Math.round(timeStart * timelineLength);
|
||||
long rightTime = Math.round((timeStart + zoom) * timelineLength);
|
||||
|
||||
// Draw markers
|
||||
if (showMarkers) {
|
||||
int markerY = positionY + HEIGHT - BORDER_BOTTOM;
|
||||
MarkerType mt = MarkerType.getMarkerType(zoom, timelineLength);
|
||||
|
||||
// Small markers
|
||||
for (int s = 0; s <= timelineLength; s += mt.smallDistance) {
|
||||
if (s <= rightTime && s >= leftTime) {
|
||||
long positionInSegment = s - leftTime;
|
||||
double fractionOfSegment = positionInSegment / (zoom * timelineLength);
|
||||
int markerX = (int) (positionX + BORDER_LEFT + fractionOfSegment * bodyWidth);
|
||||
|
||||
drawVerticalLine(markerX, markerY - 3, markerY, 0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
// Big markers
|
||||
for (int s = 0; s <= timelineLength; s += mt.distance) {
|
||||
if (s <= rightTime && s >= leftTime) {
|
||||
long positionInSegment = s - leftTime;
|
||||
double fractionOfSegment = positionInSegment / (zoom * timelineLength);
|
||||
int markerX = (int) (positionX + BORDER_LEFT + fractionOfSegment * bodyWidth);
|
||||
|
||||
drawVerticalLine(markerX, markerY - 7, markerY, 0xffc0c0c0); // Light gray
|
||||
|
||||
// Write time above the timeline
|
||||
long sec = Math.round(s / 1000.0);
|
||||
String timestamp = String.format("%02d:%02ds", sec / 60, sec % 60);
|
||||
drawCenteredString(mc.fontRendererObj, timestamp, markerX, positionY - 8, 0xffffffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the cursor if it's on the current timeline segment
|
||||
if (cursorPosition >= leftTime && cursorPosition <= rightTime) {
|
||||
long positionInSegment = cursorPosition - leftTime;
|
||||
double fractionOfSegment = positionInSegment / (zoom * timelineLength);
|
||||
int cursorX = (int) (positionX + BORDER_LEFT + fractionOfSegment * bodyWidth);
|
||||
|
||||
rect(cursorX - 2, positionY + BORDER_TOP, 84, 20, 5, 16);
|
||||
}
|
||||
|
||||
// Draw time under cursor if the mouse is on the timeline
|
||||
long mouseTime = getTimeAt(mouseX, mouseY);
|
||||
if (mouseTime != -1) {
|
||||
long sec = mouseTime / 1000;
|
||||
String timestamp = String.format("%02d:%02ds", sec / 60, sec % 60);
|
||||
drawCenteredString(mc.fontRendererObj, timestamp, mouseX, mouseY + 5, 0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
protected void rect(int x, int y, int u, int v, int width, int height) {
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(replay_gui);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
drawModalRectWithCustomSizedTexture(x, y, u, v, width, height, TEXTURE_SIZE, TEXTURE_SIZE);
|
||||
}
|
||||
|
||||
|
||||
private enum MarkerType {
|
||||
|
||||
ONE_S(1000, 100),
|
||||
FIVE_S(5 * 1000, 1000),
|
||||
QUARTER_M(15 * 1000, 3 * 1000),
|
||||
HALF_M(30 * 1000, 5 * 1000),
|
||||
ONE_M(60 * 1000, 10 * 1000),
|
||||
FIVE_M(5 * 60 * 1000, 50 * 1000);
|
||||
|
||||
int distance;
|
||||
int smallDistance;
|
||||
int maximum = 10;
|
||||
|
||||
MarkerType(int minimum, int smallDistance) {
|
||||
this.distance = minimum;
|
||||
this.smallDistance = smallDistance;
|
||||
}
|
||||
|
||||
public static MarkerType getMarkerType(double scale, long totalLength) {
|
||||
long seconds = Math.round(totalLength * scale);
|
||||
|
||||
for(MarkerType mt : values()) {
|
||||
if(seconds / mt.distance <= 10) {
|
||||
return mt;
|
||||
}
|
||||
}
|
||||
|
||||
return FIVE_M;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user