Skip to content
Permalink
Browse files

Improve default mouse cursor behavior:

- Use the default cursor if no virtual cursor is set and the mouse is not being grabbed by the window.
- Move the debug cursor handling to the MouseCursor implementation
- Don't grab the mouse by default.
  • Loading branch information
steffen-wilke committed Jan 9, 2020
1 parent 566e9cb commit 6d92e25e052a431c52bb5dd476a3dde6bb1af903
@@ -88,7 +88,7 @@
private static UpdateLoop inputLoop;
private static ScreenManager screenManager;
private static GameWindow gameWindow;

private static GameWorld world = new GameWorld();

private static boolean debug = true;
@@ -270,14 +270,15 @@ public static GameTime time() {

/**
* Gets the game's window in which the <code>RenderComponent</code> lives.<br>
* This class e.g. provides the possibility to set a title, provide an icon or get information about the resolution.
* This class e.g. provides the possibility to set a title, provide an icon, get information about the resolution or set a cursor.
*
* @return The window that hosts the game's <code>RenderComponent</code>.
*
* @see RenderComponent
* @see GameWindow#getResolution()
* @see GameWindow#setTitle(String)
* @see GameWindow#setIconImage(java.awt.Image)
* @see GameWindow#cursor()
*/
public static GameWindow window() {
return gameWindow;
@@ -1,14 +1,21 @@
package de.gurkenlabs.litiengine.graphics;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;

import de.gurkenlabs.litiengine.Align;
import de.gurkenlabs.litiengine.Game;
import de.gurkenlabs.litiengine.Valign;
import de.gurkenlabs.litiengine.input.Input;
import de.gurkenlabs.litiengine.input.Mouse;
import de.gurkenlabs.litiengine.util.Imaging;

/**
* The visual representation of the <code>Mouse</code> in the LITIengine.<br>
@@ -17,12 +24,31 @@
* @see Mouse
*/
public final class MouseCursor implements IRenderable {

private static final Cursor DEFAULT_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR);
private static final Cursor BLANK_CURSOR;
private static final Image DEBUG_CURSOR_IMAGE;

private Image image;
private AffineTransform transform;
private int offsetX;
private int offsetY;

private boolean visible;
static {
final BufferedImage cursorImg = Imaging.getCompatibleImage(16, 16);
BLANK_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");

final BufferedImage debugCursorImg = Imaging.getCompatibleImage(16, 16);
Graphics2D g = debugCursorImg.createGraphics();
g.setColor(Color.RED);
g.drawLine(0, 0, 16, 16);
g.drawLine(0, 0, 16, 0);
g.drawLine(0, 0, 0, 16);
g.dispose();

DEBUG_CURSOR_IMAGE = debugCursorImg;
}

public MouseCursor() {
this.visible = true;
@@ -34,6 +60,10 @@ public void render(Graphics2D g) {
final Point2D locationWithOffset = new Point2D.Double(Input.mouse().getLocation().getX() + this.getOffsetX(), Input.mouse().getLocation().getY() + this.getOffsetY());
ImageRenderer.renderTransformed(g, this.getImage(), locationWithOffset, this.getTransform());
}

if (Game.config().debug().isRenderDebugMouse()) {
ImageRenderer.render(g, DEBUG_CURSOR_IMAGE, Input.mouse().getLocation());
}
}

public Image getImage() {
@@ -69,6 +99,15 @@ public void set(final Image img) {
public void set(final Image img, final int offsetX, final int offsetY) {
this.image = img;
this.setOffset(offsetX, offsetY);

if (this.getImage() != null) {
hideDefaultCursor();
return;
}

if (!Input.mouse().isGrabMouse()) {
showDefaultCursor();
}
}

public void set(final Image img, Align hAlign, Valign vAlign) {
@@ -95,4 +134,12 @@ public void setTransform(AffineTransform transform) {
public void setVisible(boolean visible) {
this.visible = visible;
}

public void showDefaultCursor() {
Game.window().getRenderComponent().setCursor(DEFAULT_CURSOR);
}

public void hideDefaultCursor() {
Game.window().getRenderComponent().setCursor(BLANK_CURSOR);
}
}
@@ -2,15 +2,12 @@

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.geom.Line2D;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
@@ -23,9 +20,7 @@

import de.gurkenlabs.litiengine.Game;
import de.gurkenlabs.litiengine.gui.screens.Screen;
import de.gurkenlabs.litiengine.input.Input;
import de.gurkenlabs.litiengine.resources.ImageFormat;
import de.gurkenlabs.litiengine.util.Imaging;
import de.gurkenlabs.litiengine.util.MathUtilities;
import de.gurkenlabs.litiengine.util.TimeUtilities;
import de.gurkenlabs.litiengine.util.io.ImageSerializer;
@@ -34,7 +29,6 @@
public class RenderComponent extends Canvas {
public static final Color DEFAULT_BACKGROUND_COLOR = Color.BLACK;
public static final Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 12);
private static final int DEBUG_MOUSE_SIZE = 5;

private final transient List<IntConsumer> fpsChangedConsumer;
private final transient List<Consumer<Graphics2D>> renderedConsumer;
@@ -60,10 +54,6 @@ public RenderComponent(final Dimension size) {
this.setBackground(DEFAULT_BACKGROUND_COLOR);
this.setFont(DEFAULT_FONT);

// hide default cursor
final BufferedImage cursorImg = Imaging.getCompatibleImage(16, 16);
final Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");
this.setCursor(blankCursor);
this.setSize(size);

// canvas will scale when the size of this jframe gets changed
@@ -140,13 +130,6 @@ public void render() {

Game.window().cursor().render(g);

if (Game.config().debug().isRenderDebugMouse()) {
g.setColor(Color.RED);

g.draw(new Line2D.Double(Input.mouse().getLocation().getX(), Input.mouse().getLocation().getY() - DEBUG_MOUSE_SIZE, Input.mouse().getLocation().getX(), Input.mouse().getLocation().getY() + DEBUG_MOUSE_SIZE));
g.draw(new Line2D.Double(Input.mouse().getLocation().getX() - DEBUG_MOUSE_SIZE, Input.mouse().getLocation().getY(), Input.mouse().getLocation().getX() + DEBUG_MOUSE_SIZE, Input.mouse().getLocation().getY()));
}

for (final Consumer<Graphics2D> consumer : this.renderedConsumer) {
consumer.accept(g);
}
@@ -9,6 +9,10 @@
import java.awt.geom.Point2D;
import java.util.EventListener;

import de.gurkenlabs.litiengine.Game;
import de.gurkenlabs.litiengine.GameWindow;
import de.gurkenlabs.litiengine.graphics.MouseCursor;

/**
* The <code>IMouse</code> interface is the engine's API for receiving mouse input events.
*/
@@ -254,8 +258,16 @@
/**
* If set to true, the mouse will be locked to the render component of the game.
*
* <p>
* If this is set to true, the default cursor cannot be used anymore and instead a virtual cursor should be set.
* </p>
*
* @param grab
* True if the mouse should be grabbed to the game's window, otherwise false.
*
* @see MouseCursor#set(java.awt.Image)
* @see GameWindow#cursor()
* @see Game#window()
*/
public void setGrabMouse(boolean grab);

@@ -71,7 +71,7 @@
this.location = new Point2D.Double(Game.world().camera().getViewport().getCenterX(), Game.world().camera().getViewport().getCenterY());
this.lastLocation = this.location;
this.sensitivity = Game.config().input().getMouseSensitivity();
this.grabMouse = true;
this.grabMouse = false;

Game.inputLoop().attach(this);
}
@@ -338,6 +338,12 @@ public void clearExplicitListeners() {
@Override
public void setGrabMouse(final boolean grab) {
this.grabMouse = grab;

if (this.isGrabMouse()) {
Game.window().cursor().hideDefaultCursor();
} else if (!Game.window().cursor().isVisible()) {
Game.window().cursor().showDefaultCursor();
}
}

@Override

0 comments on commit 6d92e25

Please sign in to comment.
You can’t perform that action at this time.