Fixes #4731: Take the position where the user clicked the handle into account when calculating the new scrollbar position.
Also fixes: The scrollbar did not subtract the handle height when determining the available space for moving the handle, thus introducing drift the further down a user scrolled. Also fixes: The scrollbar did not resize it's trackbar when the ME inventory screens were resized and the number of rows changed, same for craft confirm.
This commit is contained in:
@@ -97,6 +97,8 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
|||||||
|
|
||||||
addButton(new Button(this.guiLeft + 6, this.guiTop + this.ySize - 25, 50, 20, GuiText.Cancel.text(),
|
addButton(new Button(this.guiLeft + 6, this.guiTop + this.ySize - 25, 50, 20, GuiText.Cancel.text(),
|
||||||
btn -> subGui.goBack()));
|
btn -> subGui.goBack()));
|
||||||
|
|
||||||
|
this.setScrollBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -71,8 +71,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
|||||||
public InterfaceTerminalScreen(InterfaceTerminalContainer container, PlayerInventory playerInventory,
|
public InterfaceTerminalScreen(InterfaceTerminalContainer container, PlayerInventory playerInventory,
|
||||||
ITextComponent title) {
|
ITextComponent title) {
|
||||||
super(container, playerInventory, title);
|
super(container, playerInventory, title);
|
||||||
final Scrollbar scrollbar = new Scrollbar();
|
this.setScrollBar(new Scrollbar().setLeft(175).setTop(18).setHeight(106));
|
||||||
this.setScrollBar(scrollbar);
|
|
||||||
this.xSize = 195;
|
this.xSize = 195;
|
||||||
this.ySize = 222;
|
this.ySize = 222;
|
||||||
}
|
}
|
||||||
@@ -81,10 +80,6 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
|||||||
public void init() {
|
public void init() {
|
||||||
super.init();
|
super.init();
|
||||||
|
|
||||||
this.getScrollBar().setLeft(175);
|
|
||||||
this.getScrollBar().setHeight(106);
|
|
||||||
this.getScrollBar().setTop(18);
|
|
||||||
|
|
||||||
this.searchField = new AETextField(this.font, this.guiLeft + 104, this.guiTop + 4, 65, 12);
|
this.searchField = new AETextField(this.font, this.guiLeft + 104, this.guiTop + 4, 65, 12);
|
||||||
this.searchField.setEnableBackgroundDrawing(false);
|
this.searchField.setEnableBackgroundDrawing(false);
|
||||||
this.searchField.setMaxStringLength(25);
|
this.searchField.setMaxStringLength(25);
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
|||||||
craftingGridOffsetX -= 25;
|
craftingGridOffsetX -= 25;
|
||||||
craftingGridOffsetY -= 6;
|
craftingGridOffsetY -= 6;
|
||||||
|
|
||||||
|
this.setScrollBar();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,9 +25,20 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
|||||||
import net.minecraft.client.gui.AbstractGui;
|
import net.minecraft.client.gui.AbstractGui;
|
||||||
import net.minecraft.client.renderer.Rectangle2d;
|
import net.minecraft.client.renderer.Rectangle2d;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
import appeng.client.gui.AEBaseScreen;
|
import appeng.client.gui.AEBaseScreen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements a vertical scrollbar using Vanilla's scrollbar handle texture from
|
||||||
|
* the creative tab.
|
||||||
|
* <p>
|
||||||
|
* It is expected that the background of the UI contains a pre-baked scrollbar
|
||||||
|
* track border, and that the exact rectangle of that track is set on this
|
||||||
|
* object via {@link #setLeft(int)}, {@link #setTop(int)} and
|
||||||
|
* {@link #setHeight(int)}. While the width of the track can also be set, the
|
||||||
|
* drawn handle will use vanilla's sprite width (see {@link #HANDLE_WIDTH}.
|
||||||
|
*/
|
||||||
public class Scrollbar extends AbstractGui implements IScrollSource {
|
public class Scrollbar extends AbstractGui implements IScrollSource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,6 +98,12 @@ public class Scrollbar extends AbstractGui implements IScrollSource {
|
|||||||
* True if the scrollbar's handle is currently being dragged.
|
* True if the scrollbar's handle is currently being dragged.
|
||||||
*/
|
*/
|
||||||
private boolean dragging;
|
private boolean dragging;
|
||||||
|
/**
|
||||||
|
* The y-coordinate relative to the upper edge of the scrollbar handle, where
|
||||||
|
* the user pressed the mouse button to drag. While dragging, this is applied as
|
||||||
|
* an offset to the effective scrollbar position.
|
||||||
|
*/
|
||||||
|
private int dragYOffset;
|
||||||
|
|
||||||
private final EventRepeater eventRepeater = new EventRepeater(Duration.ofMillis(250), Duration.ofMillis(150));
|
private final EventRepeater eventRepeater = new EventRepeater(Duration.ofMillis(250), Duration.ofMillis(150));
|
||||||
|
|
||||||
@@ -124,6 +141,9 @@ public class Scrollbar extends AbstractGui implements IScrollSource {
|
|||||||
* of the scrollbar's track.
|
* of the scrollbar's track.
|
||||||
*/
|
*/
|
||||||
private int getHandleYOffset() {
|
private int getHandleYOffset() {
|
||||||
|
if (getRange() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int availableHeight = this.height - HANDLE_HEIGHT;
|
int availableHeight = this.height - HANDLE_HEIGHT;
|
||||||
return (this.currentScroll - this.minScroll) * availableHeight / this.getRange();
|
return (this.currentScroll - this.minScroll) * availableHeight / this.getRange();
|
||||||
}
|
}
|
||||||
@@ -203,6 +223,11 @@ public class Scrollbar extends AbstractGui implements IScrollSource {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do nothing when there's no range, but swallow the event
|
||||||
|
if (getRange() == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int handleYOffset = getHandleYOffset();
|
int handleYOffset = getHandleYOffset();
|
||||||
|
|
||||||
if (relY < handleYOffset) {
|
if (relY < handleYOffset) {
|
||||||
@@ -213,6 +238,7 @@ public class Scrollbar extends AbstractGui implements IScrollSource {
|
|||||||
} else if (relY < handleYOffset + HANDLE_HEIGHT) {
|
} else if (relY < handleYOffset + HANDLE_HEIGHT) {
|
||||||
// Clicks on the handle will initiate dragging it
|
// Clicks on the handle will initiate dragging it
|
||||||
this.dragging = true;
|
this.dragging = true;
|
||||||
|
this.dragYOffset = relY - handleYOffset;
|
||||||
} else {
|
} else {
|
||||||
// Clicks below the handle will page down, repeatedly
|
// Clicks below the handle will page down, repeatedly
|
||||||
pageDown();
|
pageDown();
|
||||||
@@ -233,15 +259,24 @@ public class Scrollbar extends AbstractGui implements IScrollSource {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y > this.displayY && y <= this.displayY + this.height) {
|
// Compute the position of the mouse (adjusted for where it grabbed the handle,
|
||||||
this.currentScroll = (int) (y - this.displayY);
|
// so as if it grabbed
|
||||||
this.currentScroll = this.minScroll + ((this.currentScroll * 2 * this.getRange() / this.height));
|
// the upper edge of it) within the scrollable area of the track (minus the
|
||||||
this.currentScroll = (this.currentScroll + 1) >> 1;
|
// handle height).
|
||||||
this.applyRange();
|
double handleUpperEdgeY = y - this.displayY - this.dragYOffset;
|
||||||
}
|
double availableHeight = this.height - HANDLE_HEIGHT;
|
||||||
|
double position = MathHelper.clamp(handleUpperEdgeY / availableHeight, 0.0, 1.0);
|
||||||
|
|
||||||
|
this.currentScroll = this.minScroll + (int) Math.round(position * this.getRange());
|
||||||
|
this.applyRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void wheel(double delta) {
|
public void wheel(double delta) {
|
||||||
|
// Do nothing when there's no range
|
||||||
|
if (getRange() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
delta = Math.max(Math.min(-delta, 1), -1);
|
delta = Math.max(Math.min(-delta, 1), -1);
|
||||||
this.currentScroll += delta * this.pageSize;
|
this.currentScroll += delta * this.pageSize;
|
||||||
this.applyRange();
|
this.applyRange();
|
||||||
|
|||||||
Reference in New Issue
Block a user