Move some render stuff to kotlin

This commit is contained in:
DBotThePony 2022-01-18 12:16:41 +07:00
parent 083c6c216e
commit 6ed2f874a8
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 367 additions and 536 deletions

View File

@ -13,6 +13,7 @@ import ru.dbotthepony.mc.otm.client.screen.UVWindingOrder;
import java.util.Stack; import java.util.Stack;
import static org.lwjgl.opengl.GL11.GL_ALWAYS; import static org.lwjgl.opengl.GL11.GL_ALWAYS;
import static ru.dbotthepony.mc.otm.client.render.SkinElementKt.*;
/** /**
* I am too lazy to learn how Mojang's API works * I am too lazy to learn how Mojang's API works
@ -309,192 +310,6 @@ public class RenderHelper {
drawTexturedRectUV(stack, x, y, width, height, 0, 0, 1, 1); drawTexturedRectUV(stack, x, y, width, height, 0, 0, 1, 1);
} }
public static final SkinElement top_left_window_corner = new SkinElement(
WIDGETS,
18,
0,
6,
6,
256,
256
);
public static final SkinElement top_right_window_corner = new SkinElement(
WIDGETS,
24,
0,
6,
6,
256,
256
);
public static final SkinElement bottom_left_window_corner = new SkinElement(
WIDGETS,
18,
6,
6,
6,
256,
256
);
public static final SkinElement bottom_right_window_corner = new SkinElement(
WIDGETS,
24,
6,
6,
6,
256,
256
);
public static final SkinElement left_window_border = new SkinElement(
WIDGETS,
18,
4,
3,
5,
256,
256
);
public static final SkinElement right_window_border = new SkinElement(
WIDGETS,
27,
3,
3,
5,
256,
256
);
public static final SkinElement top_window_border = new SkinElement(
WIDGETS,
22,
0,
5,
3,
256,
256
);
public static final SkinElement bottom_window_border = new SkinElement(
WIDGETS,
21,
9,
5,
3,
256,
256
);
public static final SkinElement window_background = new SkinElement(
WIDGETS,
30,
12,
6,
6,
256,
256
);
public static final SkinElement scroll_bar_top = new SkinElement(
WIDGETS,
18,
57,
14,
2,
256,
256
);
public static final SkinElement scroll_bar_bottom = new SkinElement(
WIDGETS,
18,
63,
14,
2,
256,
256
);
public static final SkinElement scroll_bar_body = new SkinElement(
WIDGETS,
18,
58,
14,
6,
256,
256
);
public static final SkinElement scroll_bar_button = new SkinElement(
WIDGETS,
18,
12,
12,
15,
256,
256
);
public static final SkinElement scroll_bar_button_hover = new SkinElement(
WIDGETS,
18,
27,
12,
15,
256,
256
);
public static final SkinElement scroll_bar_button_press = new SkinElement(
WIDGETS,
18,
42,
12,
15,
256,
256
);
public static final SkinElement tab_right_connection = new SkinElement(
WIDGETS,
30,
0,
3,
5,
256,
256
);
public static final SkinElement tab_left_connection = new SkinElement(
WIDGETS,
33,
0,
3,
5,
256,
256
);
public static final SkinElement tab_background = new SkinElement(
WIDGETS,
30,
6,
6,
6,
256,
256
);
public static void drawScrollBarBackground(PoseStack stack, float x, float y, float height) {
scroll_bar_body.render(stack, x, y + 2, 14, height - 4);
scroll_bar_top.render(stack, x, y, 14, 2);
scroll_bar_bottom.render(stack, x, y + height - 2, 14, 2);
}
public static void drawRegularSlot( public static void drawRegularSlot(
PoseStack stack, PoseStack stack,
float x, float x,
@ -513,36 +328,6 @@ public class RenderHelper {
drawTexturedRectAuto(stack, x, y, 26, 26, 18, 96, 256, 256); drawTexturedRectAuto(stack, x, y, 26, 26, 18, 96, 256, 256);
} }
public static void drawWindowBackground(
PoseStack stack,
float x,
float y,
float width,
float height
) {
float bg_width = width - 4;
float bg_height = height - 4;
// background
if (bg_width > 0 && bg_height > 0) {
window_background.render(stack, x + 3, y + 3, bg_width, bg_height);
}
// borders
left_window_border.render(stack, x, y + 4, 3, height - 8);
right_window_border.renderRaw(stack, x + width - 3, y + 4, 3, height - 6);
top_window_border.renderRaw(stack, x + 4, y, width - 8, 3);
bottom_window_border.renderRaw(stack, x + 4, y + height - 3, width - 8, 3);
// corners
top_left_window_corner.renderRaw(stack, x, y, 6, 6);
top_right_window_corner.renderRaw(stack, x + width - 6, y, 6, 6);
bottom_left_window_corner.renderRaw(stack, x, y + height - 6, 6, 6);
bottom_right_window_corner.renderRaw(stack, x + width - 6, y + height - 6, 6, 6);
}
public static RGBAColor getDrawColor() { public static RGBAColor getDrawColor() {
return draw_color; return draw_color;
} }

View File

@ -1,284 +1,282 @@
package ru.dbotthepony.mc.otm.client.screen.panels; package ru.dbotthepony.mc.otm.client.screen.panels
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft
import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.narration.NarratableEntry
import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.narration.NarratableEntry.NarrationPriority
import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.client.gui.narration.NarrationElementOutput
import net.minecraft.network.chat.Component; import net.minecraft.client.resources.sounds.SimpleSoundInstance
import net.minecraft.sounds.SoundEvents; import net.minecraft.network.chat.Component
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen; import net.minecraft.sounds.SoundEvents
import ru.dbotthepony.mc.otm.client.render.RenderHelper; import org.lwjgl.opengl.GL11
import ru.dbotthepony.mc.otm.client.render.*
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import javax.annotation.Nonnull; open class FramePanel(
import javax.annotation.Nullable; screen: MatteryScreen<*>,
import java.util.ArrayList; parent: EditablePanel?,
x: Float,
import static org.lwjgl.opengl.GL11.GL_ALWAYS; y: Float,
width: Float,
public class FramePanel extends EditablePanel implements NarratableEntry { height: Float,
public enum FrameTabPosition { protected var title: Component
TOP(28, 28,28, 32), ) : EditablePanel(screen, parent, x, y, width, height), NarratableEntry {
LEFT(28, 28, 32, 28), enum class FrameTabPosition(val width: Float, val height: Float, val active_width: Float, val active_height: Float) {
RIGHT(28, 28, 32, 28), TOP(28f, 28f, 28f, 32f),
BOTTOM(28, 28, 28, 32); // TODO: а оно вообще нужно?
LEFT(28f, 28f, 32f, 28f),
public final int width; RIGHT(28f, 28f, 32f, 28f),
public final int height; BOTTOM(28f, 28f, 28f, 32f);
public final int active_width;
public final int active_height;
FrameTabPosition(int width, int height, int active_width, int active_height) {
this.width = width;
this.height = height;
this.active_width = active_width;
this.active_height = active_height;
}
} }
public class FrameTabPanel extends EditablePanel { open inner class FrameTabPanel(position: FrameTabPosition, on_open: Runnable? = null, on_close: Runnable? = null) :
public final FrameTabPosition tab_position; EditablePanel(
this@FramePanel.screen,
this@FramePanel,
0f,
0f,
position.width,
position.height
) {
public boolean isActive() { val frameTabPosition: FrameTabPosition = position
return active; var isActive = false
var initial = false
var onOpen: Runnable? = on_open
var onClose: Runnable? = on_close
open fun bindOnOpen(value: Runnable?) {
onOpen = value
} }
protected boolean active = false; open fun bindOnClose(value: Runnable?) {
protected boolean initial = false; onClose = value
protected Runnable on_open;
protected Runnable on_close;
public FrameTabPanel(FrameTabPosition position, Runnable on_open, Runnable on_close) {
super(FramePanel.this.screen, FramePanel.this, 0, 0, position.width, position.height);
tab_position = position;
this.on_open = on_open;
this.on_close = on_close;
} }
public FrameTabPanel(FrameTabPosition position) { override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
super(FramePanel.this.screen, FramePanel.this, 0, 0, position.width, position.height); if (frameTabPosition == FrameTabPosition.TOP) {
tab_position = position; val width: Float
} val height: Float
public void bindOnOpen(Runnable value) { if (isActive) {
on_open = value; width = frameTabPosition.active_width
} height = frameTabPosition.active_height
window_background.render(stack, 2f, 2f, width - 4, height - 2)
public void bindOnClose(Runnable value) {
on_close = value;
}
@Override
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
if (tab_position == FrameTabPosition.TOP) {
int width;
int height;
if (active) {
width = tab_position.active_width;
height = tab_position.active_height;
RenderHelper.window_background.render(stack, 2, 2, width - 4, height - 2);
} else { } else {
width = tab_position.width; width = frameTabPosition.width
height = tab_position.height; height = frameTabPosition.height
tab_background.render(stack, 2f, 2f, width - 4, height - 2)
RenderHelper.tab_background.render(stack, 2, 2, width - 4, height - 2);
} }
RenderHelper.top_window_border.renderW(stack, 3, 0, width - 6); top_window_border.renderW(stack, 3f, 0f, width - 6)
RenderHelper.left_window_border.renderH(stack, 0, 3, height - (active ? (initial ? 2 : 4) : 3)); left_window_border.renderH(stack, 0f, 3f, (height - if (isActive) if (initial) 2 else 4 else 3))
RenderHelper.right_window_border.renderH(stack, width - RenderHelper.right_window_border.rect_w(), 3, height - (active ? 4 : 3));
RenderHelper.top_left_window_corner.render(stack, 0, 0); right_window_border.renderH(stack, width - right_window_border.rect_w, 3f, (height - if (isActive) 4 else 3))
RenderHelper.top_right_window_corner.render(stack, width - RenderHelper.top_right_window_corner.rect_w(), 0);
if (active) { top_left_window_corner.render(stack, 0f, 0f)
top_right_window_corner.render(stack, width - top_right_window_corner.rect_w, 0f)
if (isActive) {
if (!initial) { if (!initial) {
RenderHelper.tab_left_connection.render(stack, 0, height - RenderHelper.tab_left_connection.rect_h() - 1); tab_left_connection.render(stack, 0f, height - tab_left_connection.rect_h - 1)
} }
RenderHelper.tab_right_connection.render(stack, width - RenderHelper.tab_right_connection.rect_w(), height - RenderHelper.tab_left_connection.rect_h() - 1); tab_right_connection.render(
stack,
width - tab_right_connection.rect_w,
height - tab_left_connection.rect_h - 1
)
} }
} }
} }
@Override protected open fun onOpen() {
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) { onOpen?.run()
if (active) { }
return true;
protected open fun onClose() {
onClose?.run()
}
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
if (isActive) {
return true
} }
for (var tab : top_tabs) { for (tab in tabsTop) {
if (tab != this) { if (tab !== this) {
if (tab.active) { if (tab.isActive) {
tab.on_close.run(); tab.onClose()
tab.active = false; tab.isActive = false
} }
} }
} }
for (var tab : left_tabs) { for (tab in tabsLeft) {
if (tab != this) { if (tab !== this) {
if (tab.active) { if (tab.isActive) {
tab.on_close.run(); tab.onClose()
tab.active = false; tab.isActive = false
} }
} }
} }
for (var tab : right_tabs) { for (tab in tabsRight) {
if (tab != this) { if (tab !== this) {
if (tab.active) { if (tab.isActive) {
tab.on_close.run(); tab.onClose()
tab.active = false; tab.isActive = false
} }
} }
} }
for (var tab : bottom_tabs) { for (tab in tabsBottom) {
if (tab != this) { if (tab !== this) {
if (tab.active) { if (tab.isActive) {
tab.on_close.run(); tab.onClose()
tab.active = false; tab.isActive = false
} }
} }
} }
active = true; isActive = true
on_open.run(); onOpen()
Minecraft.getInstance().soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f))
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); return true
return true;
} }
} }
protected final ArrayList<FrameTabPanel> top_tabs = new ArrayList<>(); protected val tabsTop = ArrayList<FrameTabPanel>()
protected final ArrayList<FrameTabPanel> left_tabs = new ArrayList<>(); protected val tabsLeft = ArrayList<FrameTabPanel>()
protected final ArrayList<FrameTabPanel> right_tabs = new ArrayList<>(); protected val tabsRight = ArrayList<FrameTabPanel>()
protected final ArrayList<FrameTabPanel> bottom_tabs = new ArrayList<>(); protected val tabsBottom = ArrayList<FrameTabPanel>()
public FrameTabPanel addTab(FrameTabPosition position, Runnable on_open, Runnable on_close) { @JvmOverloads
var tab = new FrameTabPanel(position, on_open, on_close); fun addTab(position: FrameTabPosition, on_open: Runnable? = null, on_close: Runnable? = null): FrameTabPanel {
doAddTab(tab); val tab = FrameTabPanel(position, on_open, on_close)
return tab; doAddTab(tab)
return tab
} }
protected void doAddTab(FrameTabPanel tab) { protected fun doAddTab(tab: FrameTabPanel) {
if (top_tabs.size() == 0 && left_tabs.size() == 0 && right_tabs.size() == 0 && bottom_tabs.size() == 0) { if (tabsTop.size == 0 && tabsLeft.size == 0 && tabsRight.size == 0 && tabsBottom.size == 0) {
tab.active = true; tab.isActive = true
} }
switch (tab.tab_position) { when (tab.frameTabPosition) {
case TOP -> top_tabs.add(tab); FrameTabPosition.TOP -> tabsTop.add(tab)
case LEFT -> left_tabs.add(tab); FrameTabPosition.LEFT -> tabsLeft.add(tab)
case RIGHT -> right_tabs.add(tab); FrameTabPosition.RIGHT -> tabsRight.add(tab)
case BOTTOM -> bottom_tabs.add(tab); FrameTabPosition.BOTTOM -> tabsBottom.add(tab)
} }
} }
public FrameTabPanel addTab(FrameTabPosition position) { override fun performLayout() {
var tab = new FrameTabPanel(position); for (i in tabsTop.indices) {
doAddTab(tab); val tab = tabsTop[i]
return tab; tab.setPos(i * FrameTabPosition.TOP.width, -FrameTabPosition.TOP.height)
} tab.initial = i == 0
@Override
protected void performLayout() {
for (int i = 0; i < top_tabs.size(); i++) {
var tab = top_tabs.get(i);
tab.setPos(i * FrameTabPosition.TOP.width, -FrameTabPosition.TOP.height);
tab.initial = i == 0;
} }
super.performLayout(); super.performLayout()
} }
protected Component title; protected var dragging = false
protected var dragMouseX = 0.0
protected var dragMouseY = 0.0
public static final int PADDING = 4; init {
public static final int PADDING_TOP = 14; setDockPadding(PADDING, PADDING_TOP, PADDING, PADDING)
public FramePanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float width, float height, Component title) {
super(screen, parent, x, y, width, height);
this.title = title;
setDockPadding(PADDING, PADDING_TOP, PADDING, PADDING);
} }
protected boolean dragging = false; override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
protected double last_mouse_x = 0; val (_, y1) = screenToLocal(mouse_x, mouse_y)
protected double last_mouse_y = 0;
@Override if (parent == null && y1 >= 0 && y1 <= 12) {
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) { ignoreMouseEventBoundaries = true
var pos = screenToLocal(mouse_x, mouse_y); dragMouseX = mouse_x
dragMouseY = mouse_y
if (getParent() == null && pos.y() >= 0 && pos.y() <= 12) { dragging = true
setIgnoreMouseEventBoundaries(true); return true
last_mouse_x = mouse_x;
last_mouse_y = mouse_y;
dragging = true;
return true;
} }
return super.mouseClickedInner(mouse_x, mouse_y, flag); return super.mouseClickedInner(mouse_x, mouse_y, flag)
} }
@Override override fun mouseReleasedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) {
if (dragging) { if (dragging) {
setIgnoreMouseEventBoundaries(false); ignoreMouseEventBoundaries = false
dragging = false
dragging = false; return true
return true;
} }
return super.mouseReleasedInner(mouse_x, mouse_y, flag); return super.mouseReleasedInner(mouse_x, mouse_y, flag)
} }
@Override override fun mouseDraggedInner(
protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) { mouse_x: Double,
mouse_y: Double,
flag: Int,
drag_x: Double,
drag_y: Double
): Boolean {
if (dragging) { if (dragging) {
var real_drag_x = mouse_x - last_mouse_x; val draggedX = mouse_x - dragMouseX
var real_drag_y = mouse_y - last_mouse_y; val draggedY = mouse_y - dragMouseY
dragMouseX = mouse_x
last_mouse_x = mouse_x; dragMouseY = mouse_y
last_mouse_y = mouse_y; setPos(x + draggedX, y + draggedY)
setPos(getX() + real_drag_x, getY() + real_drag_y);
} }
return super.mouseDraggedInner(mouse_x, mouse_y, flag, drag_x, drag_y); return super.mouseDraggedInner(mouse_x, mouse_y, flag, drag_x, drag_y)
} }
@Override override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
// background // background
// RenderSystem.disableDepthTest(); // RenderSystem.disableDepthTest();
RenderHelper.drawWindowBackground(stack, 0, 0, getWidth(), getHeight()); val bgWidth = width - 4
val bgHeight = height - 4
// background
if (bgWidth > 0 && bgHeight > 0) {
window_background.render(stack, x + 3, y + 3, bgWidth, bgHeight)
}
// borders
left_window_border.render(stack, x, y + 4, 3f, height - 8)
right_window_border.renderRaw(stack, x + width - 3, y + 4, 3f, height - 6)
top_window_border.renderRaw(stack, x + 4, y, width - 8, 3f)
bottom_window_border.renderRaw(stack, x + 4, y + height - 3, width - 8, 3f)
// corners
top_left_window_corner.renderRaw(stack, x, y, 6f, 6f)
top_right_window_corner.renderRaw(stack, x + width - 6, y, 6f, 6f)
bottom_left_window_corner.renderRaw(stack, x, y + height - 6, 6f, 6f)
bottom_right_window_corner.renderRaw(stack, x + width - 6, y + height - 6, 6f, 6f)
// RenderSystem.enableDepthTest(); // RenderSystem.enableDepthTest();
// title // title
RenderSystem.depthFunc(GL_ALWAYS); RenderSystem.depthFunc(GL11.GL_ALWAYS)
screen.getFont().draw(stack, title, 8, 5, 4210752); screen.font.draw(stack, title, 8f, 5f, 4210752)
RenderSystem.depthFunc(GL_ALWAYS); RenderSystem.depthFunc(GL11.GL_ALWAYS)
} }
@Override override fun narrationPriority(): NarrationPriority {
public NarrationPriority narrationPriority() { return NarrationPriority.NONE
return NarrationPriority.NONE;
} }
@Override override fun updateNarration(narrationElementOutput: NarrationElementOutput) {}
public void updateNarration(NarrationElementOutput narrationElementOutput) {
fun toScreenCenter() {
setPos((screen.width / 2 - (width / 2).toInt()).toFloat(), (screen.height / 2 - (height / 2).toInt()).toFloat())
} }
public void toScreenCenter() { companion object {
setPos(screen.width / 2 - (int) (getWidth() / 2), screen.height / 2 - (int) (getHeight() / 2)); const val PADDING = 4f
const val PADDING_TOP = 14f
} }
} }

View File

@ -1,172 +1,143 @@
package ru.dbotthepony.mc.otm.client.screen.panels; package ru.dbotthepony.mc.otm.client.screen.panels
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen; import ru.dbotthepony.mc.otm.client.render.*
import ru.dbotthepony.mc.otm.client.render.RenderHelper; import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import java.util.function.Consumer
import java.util.function.Supplier
import kotlin.math.floor
import javax.annotation.Nonnull; open class ScrollBarPanel(screen: MatteryScreen<*>, parent: EditablePanel?, x: Float, y: Float, height: Float) :
import javax.annotation.Nullable; EditablePanel(screen, parent, x, y, WIDTH, height) {
import java.util.function.Consumer;
import java.util.function.Supplier;
public class ScrollBarPanel extends EditablePanel { open inner class ScrollBarButtonPanel : EditablePanel(screen, this@ScrollBarPanel, 1f, 1f, 12f, 15f) {
public class ScrollBarButtonPanel extends EditablePanel { var isScrolling = false
public ScrollBarButtonPanel() { protected set
super(ScrollBarPanel.this.screen, ScrollBarPanel.this, 1, 1, 12, 15);
}
private boolean is_scrolling; override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
if (isScrolling) {
public boolean isScrolling() { scroll_bar_button_press.render(stack, 0f, 0f)
return is_scrolling; } else if (isHovered) {
} scroll_bar_button_hover.render(stack, 0f, 0f)
@Override
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
if (is_scrolling) {
RenderHelper.scroll_bar_button_press.render(stack, 0, 0);
} else if (isHovered()) {
RenderHelper.scroll_bar_button_hover.render(stack, 0, 0);
} else { } else {
RenderHelper.scroll_bar_button.render(stack, 0, 0); scroll_bar_button.render(stack, 0f, 0f)
} }
} }
private double last_mouse_y; protected var lastMouseY = 0.0
@Override override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) { isScrolling = true
is_scrolling = true; ignoreMouseEventBoundaries = true
setIgnoreMouseEventBoundaries(true); lastMouseY = mouse_y
last_mouse_y = mouse_y; return true
return true;
} }
@Override override fun mouseReleasedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) { if (isScrolling) {
if (is_scrolling) { isScrolling = false
is_scrolling = false; ignoreMouseEventBoundaries = false
setIgnoreMouseEventBoundaries(false); return true
scroll = getScroll();
return true;
} }
return false; return false
} }
@Override override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
protected boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) { return this@ScrollBarPanel.mouseScrolledInner(mouse_x, mouse_y, scroll)
return ScrollBarPanel.this.mouseScrolledInner(mouse_x, mouse_y, scroll);
} }
@Override override fun mouseDraggedInner(
protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) { mouse_x: Double,
if (is_scrolling) { mouse_y: Double,
var diff = mouse_y - last_mouse_y; flag: Int,
last_mouse_y = mouse_y; drag_x: Double,
setScrollInternal((float) (scroll + diff / ScrollBarPanel.this.getHeight())); drag_y: Double
updateScrollBarPosition(); ): Boolean {
return true; if (isScrolling) {
val diff = mouse_y - lastMouseY
lastMouseY = mouse_y
this@ScrollBarPanel.scroll = (scroll + diff / this@ScrollBarPanel.height).toFloat()
updateScrollBarPosition()
return true
} }
return false; return false
} }
} }
public static final int WIDTH = 14; val scrollButton = ScrollBarButtonPanel()
var scrollCallback: Consumer<Float>? = null
public final ScrollBarButtonPanel scroll_button = new ScrollBarButtonPanel(); var scrollMultiplier = Supplier { 0.1f }
public Consumer<Float> scroll_callback;
@Nonnull fun setupRowMultiplier(row_supplier: Supplier<Int>) {
public Supplier<Float> scroll_multiplier = () -> 0.1f; scrollMultiplier = Supplier {
val rows = row_supplier.get()
public ScrollBarPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float height) {
super(screen, parent, x, y, WIDTH, height);
}
public void setupRowMultiplier(Supplier<Integer> row_supplier) {
scroll_multiplier = () -> {
int rows = row_supplier.get();
if (rows < 1) { if (rows < 1) {
return 0f; return@Supplier 0f
} }
return 1f / rows; return@Supplier 1f / rows
};
}
protected float scroll;
protected void onScrolled(float new_scroll, float old_scroll) {
if (scroll_callback != null)
scroll_callback.accept(new_scroll);
}
public float getScroll() {
return scroll < 0 ? 0 : scroll > 1 ? 1 : scroll;
}
public void setScroll(float scroll) {
var previous = this.scroll;
this.scroll = scroll < 0 ? 0 : scroll > 1 ? 1 : scroll;
if (previous != this.scroll) {
onScrolled(this.scroll, previous);
} }
} }
protected void setScrollInternal(float scroll) { var scroll = 0f
var previous = getScroll(); get() {
this.scroll = scroll; return if (field < 0f) 0f else if (field > 1f) 1f else field
var current = getScroll();
if (previous != current) {
onScrolled(current, previous);
} }
set(scroll) {
val previous = field
field = if (scroll < 0f) 0f else if (scroll > 1f) 1f else scroll
if (previous != field) {
onScrolled(field, previous)
}
}
protected open fun onScrolled(new_scroll: Float, old_scroll: Float) {
scrollCallback?.accept(new_scroll)
} }
public void updateScrollBarPosition() { fun updateScrollBarPosition() {
scroll_button.setY(1 + (getHeight() - 2 - scroll_button.getHeight()) * getScroll()); scrollButton.y = 1 + (height - 2 - scrollButton.height) * scroll
} }
@Override override fun performLayout() {
protected void performLayout() { super.performLayout()
super.performLayout(); updateScrollBarPosition()
updateScrollBarPosition();
} }
public void translateScrollValue(int new_max, int old_max) { fun translateScrollValue(new_max: Int, old_max: Int) {
if (new_max < 1 || old_max < 1) { if (new_max < 1 || old_max < 1) {
return; return
} }
scroll = (scroll * old_max) / new_max; scroll = scroll * old_max / new_max
} }
public int getScroll(int max_rows) { fun getScroll(max_rows: Int): Int {
if (max_rows <= 1) { if (max_rows <= 1)
return 0; return 0
}
return (int) Math.floor(getScroll() * max_rows + 0.5); return floor(scroll * max_rows + 0.5).toInt()
} }
// public is for emulating input from outside // public is for emulating input from outside
@Override public override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
public boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) { this.scroll = (this.scroll - scroll * scrollMultiplier.get()).toFloat()
setScrollInternal((float) (this.scroll - scroll * scroll_multiplier.get())); updateScrollBarPosition()
updateScrollBarPosition(); return true
return true;
} }
@Override override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) { scroll_bar_body.render(stack, x, y + 2, 14f, height - 4)
RenderHelper.drawScrollBarBackground(stack, 0, 0, getHeight()); scroll_bar_top.render(stack, x, y)
scroll_bar_bottom.render(stack, x, y + height - 2)
}
companion object {
const val WIDTH = 14f
} }
} }

View File

@ -6,7 +6,7 @@ import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.mc.otm.client.screen.UVWindingOrder import ru.dbotthepony.mc.otm.client.screen.UVWindingOrder
@JvmRecord @JvmRecord
data class SkinElement( data class SkinElement @JvmOverloads constructor(
val texture: ResourceLocation = RenderHelper.WIDGETS, val texture: ResourceLocation = RenderHelper.WIDGETS,
val image_x: Float, val image_x: Float,
val image_y: Float, val image_y: Float,
@ -31,6 +31,16 @@ data class SkinElement(
renderRaw(stack, x, y, width, height, winding) renderRaw(stack, x, y, width, height, winding)
} }
@JvmOverloads
fun render(
stack: PoseStack,
x: Double,
y: Double = 0.0,
width: Double = rect_w.toDouble(),
height: Double = rect_h.toDouble(),
winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1
) = render(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding)
@JvmOverloads @JvmOverloads
fun renderPartial( fun renderPartial(
stack: PoseStack, stack: PoseStack,
@ -47,6 +57,16 @@ data class SkinElement(
renderRawPartial(stack, x, y, width, height, winding) renderRawPartial(stack, x, y, width, height, winding)
} }
@JvmOverloads
fun renderPartial(
stack: PoseStack,
x: Double,
y: Double = 0.0,
width: Double = rect_w.toDouble(),
height: Double = rect_h.toDouble(),
winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1
) = renderPartial(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding)
@JvmOverloads @JvmOverloads
fun renderW( fun renderW(
stack: PoseStack, stack: PoseStack,
@ -58,6 +78,15 @@ data class SkinElement(
render(stack, x, y, width = width, winding = winding) render(stack, x, y, width = width, winding = winding)
} }
@JvmOverloads
fun renderW(
stack: PoseStack,
x: Double,
y: Double = 0.0,
width: Double = rect_w.toDouble(),
winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1,
) = renderW(stack, x.toFloat(), y.toFloat(), width.toFloat(), winding)
@JvmOverloads @JvmOverloads
fun renderH( fun renderH(
stack: PoseStack, stack: PoseStack,
@ -69,6 +98,15 @@ data class SkinElement(
render(stack, x, y, height = height, winding = winding) render(stack, x, y, height = height, winding = winding)
} }
@JvmOverloads
fun renderH(
stack: PoseStack,
x: Double,
y: Double = 0.0,
height: Double = rect_h.toDouble(),
winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1,
) = renderH(stack, x.toFloat(), y.toFloat(), height.toFloat(), winding)
@JvmOverloads @JvmOverloads
fun renderRaw( fun renderRaw(
stack: PoseStack, stack: PoseStack,
@ -98,6 +136,16 @@ data class SkinElement(
) )
} }
@JvmOverloads
fun renderRaw(
stack: PoseStack,
x: Double,
y: Double = 0.0,
width: Double = rect_w.toDouble(),
height: Double = rect_h.toDouble(),
winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1
) = renderRaw(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding)
@JvmOverloads @JvmOverloads
fun renderRawPartial( fun renderRawPartial(
stack: PoseStack, stack: PoseStack,
@ -126,4 +174,33 @@ data class SkinElement(
winded.v1, winded.v1,
) )
} }
@JvmOverloads
fun renderRawPartial(
stack: PoseStack,
x: Double,
y: Double = 0.0,
width: Double = rect_w.toDouble(),
height: Double = rect_h.toDouble(),
winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1
) = renderRawPartial(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding)
} }
@JvmField val top_left_window_corner = SkinElement(image_x = 18f, image_y = 0f, rect_w = 6f, rect_h = 6f)
@JvmField val top_right_window_corner = SkinElement(image_x = 24f, image_y = 0f, rect_w = 6f, rect_h = 6f)
@JvmField val left_window_border = SkinElement(image_x = 18f, image_y = 4f, rect_w = 3f, rect_h = 5f)
@JvmField val right_window_border = SkinElement(image_x = 27f, image_y = 3f, rect_w = 3f, rect_h = 5f)
@JvmField val top_window_border = SkinElement(image_x = 22f, image_y = 0f, rect_w = 5f, rect_h = 3f)
@JvmField val window_background = SkinElement(image_x = 30f, image_y = 12f, rect_w = 6f, rect_h = 6f)
@JvmField val scroll_bar_top = SkinElement(image_x = 18f, image_y = 57f, rect_w = 14f, rect_h = 2f)
@JvmField val scroll_bar_bottom = SkinElement(image_x = 18f, image_y = 63f, rect_w = 14f, rect_h = 2f)
@JvmField val scroll_bar_body = SkinElement(image_x = 18f, image_y = 58f, rect_w = 14f, rect_h = 6f)
@JvmField val scroll_bar_button = SkinElement(image_x = 18f, image_y = 12f, rect_w = 12f, rect_h = 15f)
@JvmField val scroll_bar_button_hover = SkinElement(image_x = 18f, image_y = 27f, rect_w = 12f, rect_h = 15f)
@JvmField val scroll_bar_button_press = SkinElement(image_x = 18f, image_y = 42f, rect_w = 12f, rect_h = 15f)
@JvmField val tab_right_connection = SkinElement(image_x = 30f, image_y = 0f, rect_w = 3f, rect_h = 5f)
@JvmField val tab_left_connection = SkinElement(image_x = 33f, image_y = 0f, rect_w = 3f, rect_h = 5f)
@JvmField val tab_background = SkinElement(image_x = 30f, image_y = 6f, rect_w = 6f, rect_h = 6f)
@JvmField val bottom_left_window_corner = SkinElement(image_x = 18f, image_y = 6f, rect_w = 6f, rect_h = 6f)
@JvmField val bottom_right_window_corner = SkinElement(image_x = 24f, image_y = 6f, rect_w = 6f, rect_h = 6f)
@JvmField val bottom_window_border = SkinElement(image_x = 21f, image_y = 9f, rect_w = 5f, rect_h = 3f)