Skip to content

Commit

Permalink
Implement mouse capture to allow 3d scenes in the guidebook to be mor…
Browse files Browse the repository at this point in the history
…e easily rotated/panned
  • Loading branch information
shartte committed Mar 12, 2024
1 parent 6b6c37f commit 95978eb
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ default boolean mouseReleased(GuideScreen screen, int x, int y, int button) {
return false;
}

default void mouseCaptureLost() {
}

/**
* @param x X position of the mouse in document coordinates.
* @param y Y position of the mouse in document coordinates.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ public boolean mouseClicked(GuideScreen screen, int x, int y, int button) {
initialRotY = cameraSettings.getRotationY();
initialTransX = cameraSettings.getOffsetX();
initialTransY = cameraSettings.getOffsetY();
screen.captureMouse(this);
}
}
return true;
Expand All @@ -437,6 +438,11 @@ public boolean mouseReleased(GuideScreen screen, int x, int y, int button) {
return true;
}

@Override
public void mouseCaptureLost() {
pointDown = null;
}

@Override
public boolean mouseMoved(GuideScreen screen, int x, int y) {
if (interactive && pointDown != null) {
Expand Down
62 changes: 59 additions & 3 deletions src/main/java/appeng/client/guidebook/screen/GuideScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ public class GuideScreen extends Screen {
@Nullable
private String pendingScrollToAnchor;

@Nullable
private InteractiveElement mouseCaptureTarget;

private GuideScreen(GuideScreenHistory history, Guide guide, PageAnchor anchor) {
super(Component.literal("AE2 Guidebook"));
this.history = history;
Expand Down Expand Up @@ -353,6 +356,11 @@ private static void renderHoverOutline(LytDocument document, SimpleRenderContext
public void mouseMoved(double mouseX, double mouseY) {
super.mouseMoved(mouseX, mouseY);

if (mouseCaptureTarget != null) {
var docPointUnclamped = getDocumentPointUnclamped(mouseX, mouseY);
mouseCaptureTarget.mouseMoved(this, docPointUnclamped.getX(), docPointUnclamped.getY());
}

var docPoint = getDocumentPoint(mouseX, mouseY);
if (docPoint != null) {
dispatchEvent(docPoint.getX(), docPoint.getY(), el -> {
Expand Down Expand Up @@ -389,6 +397,15 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) {
return true;
}

if (mouseCaptureTarget != null) {
var currentTarget = mouseCaptureTarget;

var docPointUnclamped = getDocumentPointUnclamped(mouseX, mouseY);
currentTarget.mouseReleased(this, docPointUnclamped.getX(), docPointUnclamped.getY(), button);

releaseMouseCapture(currentTarget);
}

var docPoint = getDocumentPoint(mouseX, mouseY);
if (docPoint != null) {
return dispatchEvent(docPoint.getX(), docPoint.getY(), el -> {
Expand Down Expand Up @@ -441,6 +458,8 @@ public void reloadPage() {
}

private void loadPage(ResourceLocation pageId) {
closePage();

GuidePageTexture.releaseUsedTextures();
var page = guide.getParsedPage(pageId);

Expand All @@ -458,6 +477,13 @@ private void loadPage(ResourceLocation pageId) {
}
}

private void closePage() {
// Reset previously stored interactive elements
if (mouseCaptureTarget != null) {
releaseMouseCapture(mouseCaptureTarget);
}
}

private Iterable<LytFlowContent> extractPageTitle(GuidePage page) {
for (var block : page.document().getBlocks()) {
if (block instanceof LytHeading heading) {
Expand Down Expand Up @@ -607,14 +633,19 @@ public Point getDocumentPoint(double screenX, double screenY) {

if (screenX >= documentRect.x() && screenX < documentRect.right()
&& screenY >= documentRect.y() && screenY < documentRect.bottom()) {
var docX = (int) Math.round(screenX - documentRect.x());
var docY = (int) Math.round(screenY + scrollbar.getScrollAmount() - documentRect.y());
return new Point(docX, docY);
return getDocumentPointUnclamped(screenX, screenY);
}

return null; // Outside the document
}

private Point getDocumentPointUnclamped(double screenX, double screenY) {
var documentRect = getDocumentRect();
var docX = (int) Math.round(screenX - documentRect.x());
var docY = (int) Math.round(screenY + scrollbar.getScrollAmount() - documentRect.y());
return new Point(docX, docY);
}

/**
* Translate a point from within the document into the screen coordinate system.
*/
Expand Down Expand Up @@ -784,13 +815,38 @@ public PageCollection getGuide() {
return guide;
}

@Nullable
public InteractiveElement getMouseCaptureTarget() {
return mouseCaptureTarget;
}

public void captureMouse(InteractiveElement element) {
if (mouseCaptureTarget != element) {
if (mouseCaptureTarget != null) {
releaseMouseCapture(mouseCaptureTarget);
}
mouseCaptureTarget = element;
}
}

public void releaseMouseCapture(InteractiveElement element) {
if (mouseCaptureTarget == element) {
mouseCaptureTarget = null;
element.mouseCaptureLost();
if (mouseCaptureTarget != null) {
throw new IllegalStateException("Element " + element + " recaptured the mouse in its release event");
}
}
}

@Override
public void onClose() {
if (minecraft != null && minecraft.screen == this && this.returnToOnClose != null) {
minecraft.setScreen(this.returnToOnClose);
this.returnToOnClose = null;
return;
}
closePage();
super.onClose();
}
}

0 comments on commit 95978eb

Please sign in to comment.