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 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
@ -309,192 +310,6 @@ public class RenderHelper {
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(
PoseStack stack,
float x,
@ -513,36 +328,6 @@ public class RenderHelper {
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() {
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.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundEvents;
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen;
import ru.dbotthepony.mc.otm.client.render.RenderHelper;
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.narration.NarratableEntry
import net.minecraft.client.gui.narration.NarratableEntry.NarrationPriority
import net.minecraft.client.gui.narration.NarrationElementOutput
import net.minecraft.client.resources.sounds.SimpleSoundInstance
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvents
import org.lwjgl.opengl.GL11
import ru.dbotthepony.mc.otm.client.render.*
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import static org.lwjgl.opengl.GL11.GL_ALWAYS;
public class FramePanel extends EditablePanel implements NarratableEntry {
public enum FrameTabPosition {
TOP(28, 28,28, 32),
LEFT(28, 28, 32, 28),
RIGHT(28, 28, 32, 28),
BOTTOM(28, 28, 28, 32);
public final int width;
public final int height;
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;
}
open class FramePanel(
screen: MatteryScreen<*>,
parent: EditablePanel?,
x: Float,
y: Float,
width: Float,
height: Float,
protected var title: Component
) : EditablePanel(screen, parent, x, y, width, height), NarratableEntry {
enum class FrameTabPosition(val width: Float, val height: Float, val active_width: Float, val active_height: Float) {
TOP(28f, 28f, 28f, 32f),
// TODO: а оно вообще нужно?
LEFT(28f, 28f, 32f, 28f),
RIGHT(28f, 28f, 32f, 28f),
BOTTOM(28f, 28f, 28f, 32f);
}
public class FrameTabPanel extends EditablePanel {
public final FrameTabPosition tab_position;
open inner class FrameTabPanel(position: FrameTabPosition, on_open: Runnable? = null, on_close: Runnable? = null) :
EditablePanel(
this@FramePanel.screen,
this@FramePanel,
0f,
0f,
position.width,
position.height
) {
public boolean isActive() {
return active;
val frameTabPosition: FrameTabPosition = position
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;
protected boolean initial = false;
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;
open fun bindOnClose(value: Runnable?) {
onClose = value
}
public FrameTabPanel(FrameTabPosition position) {
super(FramePanel.this.screen, FramePanel.this, 0, 0, position.width, position.height);
tab_position = position;
}
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
if (frameTabPosition == FrameTabPosition.TOP) {
val width: Float
val height: Float
public void bindOnOpen(Runnable value) {
on_open = value;
}
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);
if (isActive) {
width = frameTabPosition.active_width
height = frameTabPosition.active_height
window_background.render(stack, 2f, 2f, width - 4, height - 2)
} else {
width = tab_position.width;
height = tab_position.height;
RenderHelper.tab_background.render(stack, 2, 2, width - 4, height - 2);
width = frameTabPosition.width
height = frameTabPosition.height
tab_background.render(stack, 2f, 2f, width - 4, height - 2)
}
RenderHelper.top_window_border.renderW(stack, 3, 0, width - 6);
RenderHelper.left_window_border.renderH(stack, 0, 3, height - (active ? (initial ? 2 : 4) : 3));
RenderHelper.right_window_border.renderH(stack, width - RenderHelper.right_window_border.rect_w(), 3, height - (active ? 4 : 3));
top_window_border.renderW(stack, 3f, 0f, width - 6)
left_window_border.renderH(stack, 0f, 3f, (height - if (isActive) if (initial) 2 else 4 else 3))
RenderHelper.top_left_window_corner.render(stack, 0, 0);
RenderHelper.top_right_window_corner.render(stack, width - RenderHelper.top_right_window_corner.rect_w(), 0);
right_window_border.renderH(stack, width - right_window_border.rect_w, 3f, (height - if (isActive) 4 else 3))
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) {
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 boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
if (active) {
return true;
protected open fun onOpen() {
onOpen?.run()
}
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) {
if (tab != this) {
if (tab.active) {
tab.on_close.run();
tab.active = false;
for (tab in tabsTop) {
if (tab !== this) {
if (tab.isActive) {
tab.onClose()
tab.isActive = false
}
}
}
for (var tab : left_tabs) {
if (tab != this) {
if (tab.active) {
tab.on_close.run();
tab.active = false;
for (tab in tabsLeft) {
if (tab !== this) {
if (tab.isActive) {
tab.onClose()
tab.isActive = false
}
}
}
for (var tab : right_tabs) {
if (tab != this) {
if (tab.active) {
tab.on_close.run();
tab.active = false;
for (tab in tabsRight) {
if (tab !== this) {
if (tab.isActive) {
tab.onClose()
tab.isActive = false
}
}
}
for (var tab : bottom_tabs) {
if (tab != this) {
if (tab.active) {
tab.on_close.run();
tab.active = false;
for (tab in tabsBottom) {
if (tab !== this) {
if (tab.isActive) {
tab.onClose()
tab.isActive = false
}
}
}
active = true;
on_open.run();
isActive = true
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 final ArrayList<FrameTabPanel> left_tabs = new ArrayList<>();
protected final ArrayList<FrameTabPanel> right_tabs = new ArrayList<>();
protected final ArrayList<FrameTabPanel> bottom_tabs = new ArrayList<>();
protected val tabsTop = ArrayList<FrameTabPanel>()
protected val tabsLeft = ArrayList<FrameTabPanel>()
protected val tabsRight = ArrayList<FrameTabPanel>()
protected val tabsBottom = ArrayList<FrameTabPanel>()
public FrameTabPanel addTab(FrameTabPosition position, Runnable on_open, Runnable on_close) {
var tab = new FrameTabPanel(position, on_open, on_close);
doAddTab(tab);
return tab;
@JvmOverloads
fun addTab(position: FrameTabPosition, on_open: Runnable? = null, on_close: Runnable? = null): FrameTabPanel {
val tab = FrameTabPanel(position, on_open, on_close)
doAddTab(tab)
return tab
}
protected void doAddTab(FrameTabPanel tab) {
if (top_tabs.size() == 0 && left_tabs.size() == 0 && right_tabs.size() == 0 && bottom_tabs.size() == 0) {
tab.active = true;
protected fun doAddTab(tab: FrameTabPanel) {
if (tabsTop.size == 0 && tabsLeft.size == 0 && tabsRight.size == 0 && tabsBottom.size == 0) {
tab.isActive = true
}
switch (tab.tab_position) {
case TOP -> top_tabs.add(tab);
case LEFT -> left_tabs.add(tab);
case RIGHT -> right_tabs.add(tab);
case BOTTOM -> bottom_tabs.add(tab);
when (tab.frameTabPosition) {
FrameTabPosition.TOP -> tabsTop.add(tab)
FrameTabPosition.LEFT -> tabsLeft.add(tab)
FrameTabPosition.RIGHT -> tabsRight.add(tab)
FrameTabPosition.BOTTOM -> tabsBottom.add(tab)
}
}
public FrameTabPanel addTab(FrameTabPosition position) {
var tab = new FrameTabPanel(position);
doAddTab(tab);
return tab;
}
@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;
override fun performLayout() {
for (i in tabsTop.indices) {
val tab = tabsTop[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;
public static final int PADDING_TOP = 14;
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);
init {
setDockPadding(PADDING, PADDING_TOP, PADDING, PADDING)
}
protected boolean dragging = false;
protected double last_mouse_x = 0;
protected double last_mouse_y = 0;
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
val (_, y1) = screenToLocal(mouse_x, mouse_y)
@Override
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
var pos = screenToLocal(mouse_x, mouse_y);
if (getParent() == null && pos.y() >= 0 && pos.y() <= 12) {
setIgnoreMouseEventBoundaries(true);
last_mouse_x = mouse_x;
last_mouse_y = mouse_y;
dragging = true;
return true;
if (parent == null && y1 >= 0 && y1 <= 12) {
ignoreMouseEventBoundaries = true
dragMouseX = mouse_x
dragMouseY = mouse_y
dragging = true
return true
}
return super.mouseClickedInner(mouse_x, mouse_y, flag);
return super.mouseClickedInner(mouse_x, mouse_y, flag)
}
@Override
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) {
override fun mouseReleasedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
if (dragging) {
setIgnoreMouseEventBoundaries(false);
dragging = false;
return true;
ignoreMouseEventBoundaries = false
dragging = false
return true
}
return super.mouseReleasedInner(mouse_x, mouse_y, flag);
return super.mouseReleasedInner(mouse_x, mouse_y, flag)
}
@Override
protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
override fun mouseDraggedInner(
mouse_x: Double,
mouse_y: Double,
flag: Int,
drag_x: Double,
drag_y: Double
): Boolean {
if (dragging) {
var real_drag_x = mouse_x - last_mouse_x;
var real_drag_y = mouse_y - last_mouse_y;
last_mouse_x = mouse_x;
last_mouse_y = mouse_y;
setPos(getX() + real_drag_x, getY() + real_drag_y);
val draggedX = mouse_x - dragMouseX
val draggedY = mouse_y - dragMouseY
dragMouseX = mouse_x
dragMouseY = mouse_y
setPos(x + draggedX, y + draggedY)
}
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
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
// background
// 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();
// title
RenderSystem.depthFunc(GL_ALWAYS);
screen.getFont().draw(stack, title, 8, 5, 4210752);
RenderSystem.depthFunc(GL_ALWAYS);
RenderSystem.depthFunc(GL11.GL_ALWAYS)
screen.font.draw(stack, title, 8f, 5f, 4210752)
RenderSystem.depthFunc(GL11.GL_ALWAYS)
}
@Override
public NarrationPriority narrationPriority() {
return NarrationPriority.NONE;
override fun narrationPriority(): NarrationPriority {
return NarrationPriority.NONE
}
@Override
public void updateNarration(NarrationElementOutput narrationElementOutput) {
override fun updateNarration(narrationElementOutput: NarrationElementOutput) {}
fun toScreenCenter() {
setPos((screen.width / 2 - (width / 2).toInt()).toFloat(), (screen.height / 2 - (height / 2).toInt()).toFloat())
}
public void toScreenCenter() {
setPos(screen.width / 2 - (int) (getWidth() / 2), screen.height / 2 - (int) (getHeight() / 2));
companion object {
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 ru.dbotthepony.mc.otm.client.screen.MatteryScreen;
import ru.dbotthepony.mc.otm.client.render.RenderHelper;
import com.mojang.blaze3d.vertex.PoseStack
import ru.dbotthepony.mc.otm.client.render.*
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;
import javax.annotation.Nullable;
import java.util.function.Consumer;
import java.util.function.Supplier;
open class ScrollBarPanel(screen: MatteryScreen<*>, parent: EditablePanel?, x: Float, y: Float, height: Float) :
EditablePanel(screen, parent, x, y, WIDTH, height) {
public class ScrollBarPanel extends EditablePanel {
public class ScrollBarButtonPanel extends EditablePanel {
public ScrollBarButtonPanel() {
super(ScrollBarPanel.this.screen, ScrollBarPanel.this, 1, 1, 12, 15);
}
open inner class ScrollBarButtonPanel : EditablePanel(screen, this@ScrollBarPanel, 1f, 1f, 12f, 15f) {
var isScrolling = false
protected set
private boolean is_scrolling;
public boolean isScrolling() {
return is_scrolling;
}
@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);
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
if (isScrolling) {
scroll_bar_button_press.render(stack, 0f, 0f)
} else if (isHovered) {
scroll_bar_button_hover.render(stack, 0f, 0f)
} 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
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
is_scrolling = true;
setIgnoreMouseEventBoundaries(true);
last_mouse_y = mouse_y;
return true;
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
isScrolling = true
ignoreMouseEventBoundaries = true
lastMouseY = mouse_y
return true
}
@Override
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) {
if (is_scrolling) {
is_scrolling = false;
setIgnoreMouseEventBoundaries(false);
scroll = getScroll();
return true;
override fun mouseReleasedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
if (isScrolling) {
isScrolling = false
ignoreMouseEventBoundaries = false
return true
}
return false;
return false
}
@Override
protected boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) {
return ScrollBarPanel.this.mouseScrolledInner(mouse_x, mouse_y, scroll);
override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
return this@ScrollBarPanel.mouseScrolledInner(mouse_x, mouse_y, scroll)
}
@Override
protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
if (is_scrolling) {
var diff = mouse_y - last_mouse_y;
last_mouse_y = mouse_y;
setScrollInternal((float) (scroll + diff / ScrollBarPanel.this.getHeight()));
updateScrollBarPosition();
return true;
override fun mouseDraggedInner(
mouse_x: Double,
mouse_y: Double,
flag: Int,
drag_x: Double,
drag_y: Double
): Boolean {
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();
public Consumer<Float> scroll_callback;
var scrollMultiplier = Supplier { 0.1f }
@Nonnull
public Supplier<Float> scroll_multiplier = () -> 0.1f;
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();
fun setupRowMultiplier(row_supplier: Supplier<Int>) {
scrollMultiplier = Supplier {
val rows = row_supplier.get()
if (rows < 1) {
return 0f;
return@Supplier 0f
}
return 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);
return@Supplier 1f / rows
}
}
protected void setScrollInternal(float scroll) {
var previous = getScroll();
this.scroll = scroll;
var current = getScroll();
if (previous != current) {
onScrolled(current, previous);
var scroll = 0f
get() {
return if (field < 0f) 0f else if (field > 1f) 1f else field
}
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() {
scroll_button.setY(1 + (getHeight() - 2 - scroll_button.getHeight()) * getScroll());
fun updateScrollBarPosition() {
scrollButton.y = 1 + (height - 2 - scrollButton.height) * scroll
}
@Override
protected void performLayout() {
super.performLayout();
updateScrollBarPosition();
override fun performLayout() {
super.performLayout()
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) {
return;
return
}
scroll = (scroll * old_max) / new_max;
scroll = scroll * old_max / new_max
}
public int getScroll(int max_rows) {
if (max_rows <= 1) {
return 0;
}
fun getScroll(max_rows: Int): Int {
if (max_rows <= 1)
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
@Override
public boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) {
setScrollInternal((float) (this.scroll - scroll * scroll_multiplier.get()));
updateScrollBarPosition();
return true;
public override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
this.scroll = (this.scroll - scroll * scrollMultiplier.get()).toFloat()
updateScrollBarPosition()
return true
}
@Override
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
RenderHelper.drawScrollBarBackground(stack, 0, 0, getHeight());
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
scroll_bar_body.render(stack, x, y + 2, 14f, height - 4)
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
@JvmRecord
data class SkinElement(
data class SkinElement @JvmOverloads constructor(
val texture: ResourceLocation = RenderHelper.WIDGETS,
val image_x: Float,
val image_y: Float,
@ -31,6 +31,16 @@ data class SkinElement(
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
fun renderPartial(
stack: PoseStack,
@ -47,6 +57,16 @@ data class SkinElement(
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
fun renderW(
stack: PoseStack,
@ -58,6 +78,15 @@ data class SkinElement(
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
fun renderH(
stack: PoseStack,
@ -69,6 +98,15 @@ data class SkinElement(
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
fun renderRaw(
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
fun renderRawPartial(
stack: PoseStack,
@ -126,4 +174,33 @@ data class SkinElement(
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)