New item monitor interface prototype

This commit is contained in:
DBotThePony 2022-06-22 16:36:43 +07:00
parent 3fe0a43333
commit c7181afc43
Signed by: DBot
GPG Key ID: DCC23B5715498507
9 changed files with 299 additions and 93 deletions

View File

@ -1,10 +1,14 @@
package ru.dbotthepony.mc.otm.client.render;
public enum UVWindingOrder {
NORMAL(0, 1, 2, 3), // normal operation
U0_V0_U1_V1(0, 1, 2, 3), // normal operation
U0_V1_U1_V0(0, 3, 2, 1), // mirror y
FLIP(0, 3, 2, 1), // mirror y
U1_V0_U0_V1(2, 1, 0, 3), // mirror x
U1_V1_U0_V0(2, 3, 0, 1); // mirror both
FLOP(2, 1, 0, 3), // mirror x
U1_V1_U0_V0(2, 3, 0, 1), // mirror both
FLIP_FLOP(2, 3, 0, 1); // mirror both
public static final int U0 = 0;
public static final int V0 = 1;

View File

@ -11,23 +11,26 @@ class SkinGrid(
val rows: Int = 16,
val columns: Int = 16,
) {
private var row = 0
private var column = 0
var row = 0
var column = 0
val imageWidth get() = width * columns
val imageHeight get() = height * rows
fun skip() {
fun skip(): SkinGrid {
column++
if (column >= columns) {
jump()
}
return this
}
fun jump() {
fun jump(): SkinGrid {
row++
column = 0
return this
}
fun next(): SkinElement {
@ -35,6 +38,25 @@ class SkinGrid(
skip()
return element
}
fun reset(): SkinGrid {
row = 0
column = 0
return this
}
fun seek(row: Int, column: Int): SkinGrid {
this.row = row
this.column = column
return this
}
operator fun get(column: Int, row: Int) = SkinElement(texture, column * width, row * height, width, height, imageWidth, imageHeight)
companion object {
val WIDGETS_18 = SkinGrid(RenderHelper.WIDGETS_18, 18f, 18f)
val WIDGETS_8 = SkinGrid(RenderHelper.WIDGETS_8, 8f, 8f)
}
}
fun ResourceLocation.element(

View File

@ -1,52 +1,133 @@
package ru.dbotthepony.mc.otm.client.screen
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Component) :
MatteryScreen<ItemMonitorMenu>(menu, inventory, title) {
override fun makeMainFrame(): FramePanel {
val frame = FramePanel(this, null, 0f, 0f, FRAME_WIDTH, FRAME_HEIGHT, getTitle())
val frame = object : FramePanel(this@ItemMonitorScreen, null, 0f, 0f, FRAME_WIDTH, FRAME_HEIGHT, getTitle()) {
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
super.innerRender(stack, mouse_x, mouse_y, flag)
// ProgressGaugePanel.GAUGE_BACKGROUND.render(stack, 28f + 3 * 18f + 6f, (ITEM_GRID_HEIGHT + 1) * 18f + 16f + 6f)
}
}
PowerGaugePanel(this, frame, menu.powerWidget, 8f, 29f)
SlotPanel(this, frame, menu.batterySlot, 8f, 80f)
val topPanel = EditablePanel(this, frame)
topPanel.height = ITEM_GRID_HEIGHT * 18f
topPanel.dock = Dock.TOP
val scrollBar = ScrollBarPanel(this, frame, 192f, 14f, 92f)
scrollBar.setupRowMultiplier { menu.view.itemCount / GRID_WIDTH }
val bottomPanel = EditablePanel(this, frame)
bottomPanel.height = 3 * 18f
bottomPanel.dock = Dock.TOP
bottomPanel.setDockMargin(top = 6f)
val gridPanel = GridPanel(this, frame, 28f, 16f, GRID_WIDTH * 18f, GRID_HEIGHT * 18f, GRID_WIDTH, GRID_HEIGHT)
frame.height = topPanel.height + bottomPanel.height + frame.dockPadding.top + frame.dockPadding.bottom + 6f
frame.width = 178f + frame.dockPadding.left + frame.dockPadding.right
for (i in 0 until GRID_WIDTH * GRID_HEIGHT) {
val viewScrollBar = ScrollBarPanel(this, topPanel, 28f + ITEM_GRID_WIDTH * 18f + 2f, 16f, ITEM_GRID_HEIGHT * 18f)
viewScrollBar.setupRowMultiplier { menu.view.itemCount / ITEM_GRID_WIDTH }
viewScrollBar.dock = Dock.RIGHT
viewScrollBar.setDockMargin(left = 2f)
val gridPanel = GridPanel(this, topPanel, width = ITEM_GRID_WIDTH * 18f, height = ITEM_GRID_HEIGHT * 18f, columns = ITEM_GRID_WIDTH, rows = ITEM_GRID_HEIGHT)
gridPanel.dock = Dock.FILL
for (i in 0 until ITEM_GRID_WIDTH * ITEM_GRID_HEIGHT) {
object : AbstractSlotPanel(this@ItemMonitorScreen, gridPanel) {
override fun getItemStack(): ItemStack {
val index = i + scrollBar.getScroll(menu.view.itemCount / GRID_WIDTH) * GRID_WIDTH
val index = i + viewScrollBar.getScroll(menu.view.itemCount / ITEM_GRID_WIDTH) * ITEM_GRID_WIDTH
return menu.view.sortedView.getOrNull(index)?.stack ?: ItemStack.EMPTY
}
override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
return scrollBar.mouseScrolledInner(mouse_x, mouse_y, scroll)
return viewScrollBar.mouseScrolledInner(mouse_x, mouse_y, scroll)
}
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
val index = i + scrollBar.getScroll(menu.view.itemCount / GRID_WIDTH) * GRID_WIDTH
val index = i + viewScrollBar.getScroll(menu.view.itemCount / ITEM_GRID_WIDTH) * ITEM_GRID_WIDTH
menu.view.mouseClick(index, mouse_click_type)
return true
}
}
}
val craftingGrid = GridPanel(this, bottomPanel, width = 3 * 18f, height = 3 * 18f, columns = 3, rows = 3)
craftingGrid.dock = Dock.LEFT
for (i in 0 until 9) {
object : AbstractSlotPanel(this@ItemMonitorScreen, craftingGrid) {
override fun getItemStack(): ItemStack {
return ItemStack(Items.APPLE, i + 1)
}
}
}
val arrowAndButtons = object : EditablePanel(this@ItemMonitorScreen, bottomPanel, width = ProgressGaugePanel.GAUGE_BACKGROUND.w) {
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
ProgressGaugePanel.GAUGE_BACKGROUND.render(stack, y = height / 2f - ProgressGaugePanel.GAUGE_BACKGROUND.h / 2f)
}
}
arrowAndButtons.dock = Dock.LEFT
arrowAndButtons.setDockMargin(left = 4f)
val arrowLine = EditablePanel(this, arrowAndButtons, y = 8f, height = 8f, width = arrowAndButtons.width)
val autoRefillMatchMode = SmallSquareButtonPanel(this, arrowLine)
val refillPriority = SmallSquareButtonPanel(this, arrowLine)
refillPriority.setDockMargin(2f)
autoRefillMatchMode.dock = Dock.LEFT
refillPriority.dock = Dock.LEFT
val resultAndButtons = EditablePanel(this, bottomPanel, width = 18f)
resultAndButtons.dock = Dock.LEFT
resultAndButtons.setDockMargin(left = 6f)
val craftingResultSlot = object : AbstractSlotPanel(this@ItemMonitorScreen, resultAndButtons, y = 18f) {
override fun getItemStack(): ItemStack {
return ItemStack(Items.BREAD, 666)
}
}
val whereToPutResult = SmallSquareButtonPanel(this, resultAndButtons, y = 8f)
val howMuchToCraft = SmallSquareButtonPanel(this, resultAndButtons, x = 10f, y = 8f)
val craftingHistory = GridPanel(this, bottomPanel, width = 3 * 18f, height = 3 * 18f, columns = 3, rows = 3)
craftingHistory.dock = Dock.LEFT
craftingHistory.setDockMargin(left = 4f)
for (i in 0 until 9) {
object : AbstractSlotPanel(this@ItemMonitorScreen, craftingHistory) {
override fun getItemStack(): ItemStack {
return ItemStack(Items.ARROW, 42)
}
}
}
val craftingHistoryScroll = ScrollBarPanel(this, bottomPanel, 0f, 0f, 0f)
craftingHistoryScroll.dock = Dock.LEFT
craftingHistoryScroll.setDockMargin(left = 2f)
return frame
}
companion object {
const val FRAME_WIDTH = 210f
const val FRAME_HEIGHT = 110f
const val GRID_WIDTH = 9
const val GRID_HEIGHT = 5
const val FRAME_WIDTH = 240f
const val FRAME_HEIGHT = 210f
const val ITEM_GRID_WIDTH = 9
const val ITEM_GRID_HEIGHT = 5
}
}

View File

@ -1,8 +1,17 @@
package ru.dbotthepony.mc.otm.client.screen.panels
import com.mojang.blaze3d.vertex.PoseStack
import com.sun.jna.platform.win32.WinUser.SIZE
import net.minecraft.client.gui.components.Button
import net.minecraft.client.gui.components.Button.OnPress
import net.minecraft.client.resources.sounds.SimpleSoundInstance
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvents
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.render.RenderHelper
import ru.dbotthepony.mc.otm.client.render.SkinElement
import ru.dbotthepony.mc.otm.client.render.SkinGrid
import ru.dbotthepony.mc.otm.client.render.element
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
open class ButtonPanel(
@ -43,3 +52,110 @@ open class ButtonPanel(
callback?.run()
}
}
@Suppress("PropertyName")
abstract class SquareButtonPanel(
screen: MatteryScreen<*>,
parent: EditablePanel?,
x: Float = 0f,
y: Float = 0f,
width: Float,
height: Float,
var skinElement: SkinElement? = null,
val lambdaOnPress: (() -> Unit)? = null,
) : EditablePanel(screen, parent, x, y, width, height) {
protected var pressed = false
abstract val PRESSED: SkinElement
abstract val HOVERED: SkinElement
abstract val IDLE: SkinElement
var isDisabled = false
set(value) {
if (field != value) {
if (!value) {
pressed = false
trapMouseInput = false
}
field = value
}
}
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
if (pressed) {
PRESSED.render(stack, 0f, 0f, width, height)
} else if (isHovered && !isDisabled) {
HOVERED.render(stack, 0f, 0f, width, height)
} else {
IDLE.render(stack, 0f, 0f, width, height)
}
skinElement?.render(stack, 0f, 0f, width, height)
}
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
if (!isDisabled) {
if (!pressed) {
minecraft.soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f))
}
pressed = true
trapMouseInput = true
}
return true
}
override fun mouseReleasedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
if (!isDisabled && pressed) {
pressed = false
if (isHovered) {
lambdaOnPress?.invoke()
}
}
trapMouseInput = false
return true
}
}
open class LargeSquareButtonPanel(
screen: MatteryScreen<*>,
parent: EditablePanel?,
x: Float = 0f,
y: Float = 0f,
width: Float = SIZE,
height: Float = SIZE,
skinElement: SkinElement? = null,
lambdaOnPress: (() -> Unit)? = null,
) : SquareButtonPanel(screen, parent, x, y, width, height, skinElement, lambdaOnPress) {
final override val IDLE = SkinGrid.WIDGETS_18[0, 0]
final override val HOVERED = SkinGrid.WIDGETS_18[1, 0]
final override val PRESSED = SkinGrid.WIDGETS_18[2, 0]
companion object {
const val SIZE = 18f
}
}
open class SmallSquareButtonPanel(
screen: MatteryScreen<*>,
parent: EditablePanel?,
x: Float = 0f,
y: Float = 0f,
width: Float = SIZE,
height: Float = SIZE,
skinElement: SkinElement? = null,
lambdaOnPress: (() -> Unit)? = null,
) : SquareButtonPanel(screen, parent, x, y, width, height, skinElement, lambdaOnPress) {
final override val IDLE = SkinGrid.WIDGETS_8[0, 0]
final override val HOVERED = SkinGrid.WIDGETS_8[0, 0]
final override val PRESSED = SkinGrid.WIDGETS_8[0, 0]
companion object {
const val SIZE = 8f
}
}

View File

@ -20,13 +20,13 @@ open class DraggableCanvasPanel @JvmOverloads constructor(
dragging = true
lastMouseX = mouse_x
lastMouseY = mouse_y
ignoreMouseEventBoundaries = true
trapMouseInput = true
return true
}
override fun mouseReleasedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
dragging = false
ignoreMouseEventBoundaries = false
trapMouseInput = false
return true
}

View File

@ -145,7 +145,7 @@ open class EditablePanel @JvmOverloads constructor(
var acceptMouseInput = true
var acceptKeyboardInput = true
var ignoreMouseEventBoundaries = false
var trapMouseInput = false
@JvmOverloads
fun setDockMargin(left: Float = 0f, top: Float = 0f, right: Float = 0f, bottom: Float = 0f) {
@ -654,13 +654,13 @@ open class EditablePanel @JvmOverloads constructor(
return children[int]
}
fun isIgnoringMouseEventBoundaries(): Boolean {
if (ignoreMouseEventBoundaries) {
fun isTrappingMouseInput(): Boolean {
if (trapMouseInput) {
return true
}
for (child in children) {
if (child.isIgnoringMouseEventBoundaries()) {
if (child.isTrappingMouseInput()) {
return true
}
}
@ -707,7 +707,7 @@ open class EditablePanel @JvmOverloads constructor(
final override fun mouseClicked(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (ignoreMouseEventBoundaries) return mouseClickedInner(mouse_x, mouse_y, flag)
if (trapMouseInput) return mouseClickedInner(mouse_x, mouse_y, flag)
for (child in children) {
if (child.mouseClickedChecked(mouse_x, mouse_y, flag)) {
@ -722,7 +722,7 @@ open class EditablePanel @JvmOverloads constructor(
fun mouseClickedChecked(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (isIgnoringMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
if (isTrappingMouseInput() || withinBounds(mouse_x, mouse_y)) {
if (acceptMouseInput && parent == null) screen.popup(this)
return mouseClicked(mouse_x, mouse_y, flag)
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
@ -748,7 +748,7 @@ open class EditablePanel @JvmOverloads constructor(
final override fun mouseReleased(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (ignoreMouseEventBoundaries) return mouseReleasedInner(mouse_x, mouse_y, flag)
if (trapMouseInput) return mouseReleasedInner(mouse_x, mouse_y, flag)
for (child in children) {
if (child.mouseReleasedChecked(mouse_x, mouse_y, flag)) {
@ -762,7 +762,7 @@ open class EditablePanel @JvmOverloads constructor(
fun mouseReleasedChecked(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (isIgnoringMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
if (isTrappingMouseInput() || withinBounds(mouse_x, mouse_y)) {
return mouseReleased(mouse_x, mouse_y, flag)
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
for (child in children) {
@ -789,7 +789,7 @@ open class EditablePanel @JvmOverloads constructor(
final override fun mouseDragged(mouse_x: Double, mouse_y: Double, flag: Int, drag_x: Double, drag_y: Double): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (ignoreMouseEventBoundaries) return mouseDraggedInner(mouse_x, mouse_y, flag, drag_x, drag_y)
if (trapMouseInput) return mouseDraggedInner(mouse_x, mouse_y, flag, drag_x, drag_y)
for (child in children) {
if (child.mouseDraggedChecked(mouse_x, mouse_y, flag, drag_x, drag_y)) {
@ -803,7 +803,7 @@ open class EditablePanel @JvmOverloads constructor(
fun mouseDraggedChecked(mouse_x: Double, mouse_y: Double, flag: Int, drag_x: Double, drag_y: Double): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (isIgnoringMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
if (isTrappingMouseInput() || withinBounds(mouse_x, mouse_y)) {
return mouseDragged(mouse_x, mouse_y, flag, drag_x, drag_y)
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
for (child in children) {
@ -824,7 +824,7 @@ open class EditablePanel @JvmOverloads constructor(
final override fun mouseScrolled(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (ignoreMouseEventBoundaries) return mouseScrolledInner(mouse_x, mouse_y, scroll)
if (trapMouseInput) return mouseScrolledInner(mouse_x, mouse_y, scroll)
for (child in children) {
if (child.mouseScrolledChecked(mouse_x, mouse_y, scroll)) {
@ -838,7 +838,7 @@ open class EditablePanel @JvmOverloads constructor(
fun mouseScrolledChecked(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (isIgnoringMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
if (isTrappingMouseInput() || withinBounds(mouse_x, mouse_y)) {
return mouseScrolled(mouse_x, mouse_y, scroll)
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
for (child in children) {
@ -917,7 +917,7 @@ open class EditablePanel @JvmOverloads constructor(
mouse_y: Double
): Boolean { // called to check whenever we are hovering at this
if (!isVisible() || !acceptMouseInput) return false
if (isIgnoringMouseEventBoundaries()) return true
if (isTrappingMouseInput()) return true
val pos = localToScreen()
return mouse_x >= pos.x && mouse_x <= pos.x + width && mouse_y >= pos.y && mouse_y + height <= pos.y

View File

@ -210,7 +210,7 @@ open class FramePanel(
val (_, y1) = screenToLocal(mouse_x, mouse_y)
if (parent == null && y1 >= 0 && y1 <= 12) {
ignoreMouseEventBoundaries = true
trapMouseInput = true
dragMouseX = mouse_x
dragMouseY = mouse_y
dragging = true
@ -222,7 +222,7 @@ open class FramePanel(
override fun mouseReleasedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
if (dragging) {
ignoreMouseEventBoundaries = false
trapMouseInput = false
dragging = false
return true
}
@ -290,7 +290,7 @@ open class FramePanel(
}
companion object {
const val PADDING = 4f
const val PADDING = 8f
const val PADDING_TOP = 14f
val top_left_window_corner = SkinElement(RenderHelper.WIDGETS, x = 18f, y = 0f, w = 6f, h = 6f)

View File

@ -1,65 +1,48 @@
package ru.dbotthepony.mc.otm.client.screen.panels;
package ru.dbotthepony.mc.otm.client.screen.panels
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen;
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
open class GridPanel(
screen: MatteryScreen<*>,
parent: EditablePanel?,
x: Float = 0f,
y: Float = 0f,
width: Float,
height: Float,
protected var columns: Int,
protected var rows: Int
) : EditablePanel(screen, parent, x, y, width, height) {
override fun performLayout() {
var currentX = 0f
var currentY = 0f
var lineY = 0f
var index = 0
public class GridPanel extends EditablePanel {
protected int grid_width;
protected int grid_height;
for (row in 0 until rows) {
var column = 0
public GridPanel(
@Nonnull MatteryScreen<?> screen,
@Nullable EditablePanel parent,
float x,
float y,
float width,
float height,
int grid_width,
int grid_height
) {
super(screen, parent, x, y, width, height);
this.grid_width = grid_width;
this.grid_height = grid_height;
}
while (column < columns) {
val child = get(index) ?: break
@Override
protected void performLayout() {
float current_x = 0;
float current_y = 0;
float line_y = 0;
int index = 0;
for (int row = 0; row < grid_height; row++) {
for (int column = 0; column < grid_width; column++) {
var child = get(index);
if (child == null) {
break;
}
if (child.getVisible() && child.getDock() == Dock.NONE) {
line_y = Math.max(line_y, child.getHeight() + child.getDockMargin().top() + child.getDockMargin().bottom());
child.setPos(current_x + child.getDockMargin().left(), current_y + child.getDockMargin().top());
current_x += child.getWidth() + child.getDockMargin().left() + child.getDockMargin().right();
if (child.visible && child.dock === Dock.NONE) {
lineY = lineY.coerceAtLeast(child.height + child.dockMargin.top + child.dockMargin.bottom)
child.setPos(currentX + child.dockMargin.left, currentY + child.dockMargin.top)
currentX += child.width + child.dockMargin.left + child.dockMargin.right
} else {
column--;
column--
}
index++;
index++
column++
}
current_y += line_y;
current_x = 0;
line_y = 0;
currentY += lineY
currentX = 0f
lineY = 0f
if (get(index) == null) {
break;
}
get(index) ?: break
}
super.performLayout();
super.performLayout()
}
}

View File

@ -7,7 +7,7 @@ import java.util.function.Consumer
import java.util.function.Supplier
import kotlin.math.floor
open class ScrollBarPanel(screen: MatteryScreen<*>, parent: EditablePanel?, x: Float, y: Float, height: Float) :
open class ScrollBarPanel(screen: MatteryScreen<*>, parent: EditablePanel?, x: Float = 0f, y: Float = 0f, height: Float = 20f) :
EditablePanel(screen, parent, x, y, WIDTH, height) {
open inner class ScrollBarButtonPanel : EditablePanel(screen, this@ScrollBarPanel, 1f, 1f, 12f, 15f) {
@ -28,7 +28,7 @@ open class ScrollBarPanel(screen: MatteryScreen<*>, parent: EditablePanel?, x: F
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
isScrolling = true
ignoreMouseEventBoundaries = true
trapMouseInput = true
lastMouseY = mouse_y
return true
}
@ -36,7 +36,7 @@ open class ScrollBarPanel(screen: MatteryScreen<*>, parent: EditablePanel?, x: F
override fun mouseReleasedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
if (isScrolling) {
isScrolling = false
ignoreMouseEventBoundaries = false
trapMouseInput = false
return true
}