<entry key="com.zeroturnaround.jrebel.remoting.DeleteUnindexedFiles" value="false" />
<entry key="com.zeroturnaround.jrebel.remoting.ModuleRemoteServerSelection" value="off" />
<entry key="jrebelEnabled" value="true" />
- <entry key="lastExternalPluginCheckTime" value="1531210862024" />
+ <entry key="lastExternalPluginCheckTime" value="1545854124608" />
</map>
</option>
<option name="masterModuleName" />
return this;
}
+ @Override
+ public String toString() {
+ return "Point2D{" +
+ "x=" + x +
+ ", y=" + y +
+ '}';
+ }
}
public int frameNumber = 0;
/**
- * Mouse click. During rendering we can detect which item user clicked on.
+ * UI component that mouse is currently hovering over.
*/
- public MouseEvent mouseEvent;
+ private MouseInteractionController currentMouseOverComponent;
+
+ public void prepareForNewFrameRendering(){
+ mouseEvent = null;
+ objectUnderMouse = null;
+ }
+
+ /**
+ * Mouse click event that needs to be processed.
+ */
+ private MouseEvent mouseEvent;
+
+ public void setMouseEvent(MouseEvent mouseEvent) {
+ this.mouseEvent = mouseEvent;
+ }
+
+ public MouseEvent getMouseEvent() {
+ return mouseEvent;
+ }
/**
* Item that user clicked on.
*/
- public MouseInteractionController objectUnderMouse;
+ private MouseInteractionController objectUnderMouse;
+
+ /**
+ * Called when given object was detected under mouse cursor, while processing {@link #mouseEvent}.
+ * Because objects are rendered back to front. The last method caller will set the top-most object, if
+ * there are multiple objects under mouse cursor.
+ */
+ public void setObjectUnderMouse(MouseInteractionController objectUnderMouse) {
+ this.objectUnderMouse = objectUnderMouse;
+ }
public RenderingContext(final int width, final int height) {
this.width = width;
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
+ /**
+ * @return <code>true</code> if view repaint is needed.
+ */
+ public boolean handleDetectedComponentMouseEvents() {
+ if (objectUnderMouse != null) {
+ if (mouseEvent.button == 0) {
+ // mouse over
+ if (currentMouseOverComponent == null) {
+ currentMouseOverComponent = objectUnderMouse;
+ return currentMouseOverComponent.mouseEntered();
+ } else if (currentMouseOverComponent != objectUnderMouse) {
+ boolean viewRepaintNeeded = currentMouseOverComponent.mouseExited();
+ currentMouseOverComponent = objectUnderMouse;
+ return viewRepaintNeeded | currentMouseOverComponent.mouseEntered();
+ }
+ } else {
+ // mouse click
+ return objectUnderMouse.mouseClicked();
+ }
+ } else if (currentMouseOverComponent != null) {
+ boolean viewRepaintNeeded = currentMouseOverComponent.mouseExited();
+ currentMouseOverComponent = null;
+ return viewRepaintNeeded;
+ }
+ return false;
+ }
+
}
import eu.svjatoslav.sixth.e3d.gui.humaninput.HIDInputTracker;
import eu.svjatoslav.sixth.e3d.gui.humaninput.KeyboardFocusStack;
-import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection;
import javax.swing.*;
private Timer canvasUpdateTimer;
private ViewUpdateTimerTask canvasUpdateTimerTask;
private RenderingContext renderingContext = null;
- /**
- * UI component that mouse is currently hovering over.
- */
- private MouseInteractionController currentMouseOverComponent;
/**
* Currently target FPS for this view. It can be changed at runtime. Also when nothing
* changes in the view, then frames are not really repainted.
* immediately after frame got updated.
*/
private boolean viewRepaintNeeded = true;
+
public ViewPanel() {
viewRenderListeners.add(avatar);
viewRenderListeners.add(HIDInputTracker);
return renderingContext;
}
- private void handleDetectedComponentMouseEvents() {
- if (renderingContext.objectUnderMouse != null) {
- if (renderingContext.mouseEvent.button == 0) {
- // mouse over
- if (currentMouseOverComponent == null) {
- currentMouseOverComponent = renderingContext.objectUnderMouse;
- viewRepaintNeeded |= currentMouseOverComponent.mouseEntered();
- } else if (currentMouseOverComponent != renderingContext.objectUnderMouse) {
- viewRepaintNeeded |= currentMouseOverComponent.mouseExited();
- currentMouseOverComponent = renderingContext.objectUnderMouse;
- viewRepaintNeeded |= currentMouseOverComponent.mouseEntered();
- }
- } else {
- // mouse click
- viewRepaintNeeded |= renderingContext.objectUnderMouse.mouseClicked();
- }
- } else if (currentMouseOverComponent != null) {
- viewRepaintNeeded |= currentMouseOverComponent.mouseExited();
- currentMouseOverComponent = null;
- }
- }
-
private void initializePanelLayout() {
setFocusCycleRoot(true);
setOpaque(true);
}
private void renderFrame() {
-
// paint root geometry collection to the offscreen render buffer
clearCanvas();
rootShapeCollection.paint(this, renderingContext);
// abort rendering if window size is invalid
if ((getWidth() > 0) && (getHeight() > 0) && renderFrame) {
renderFrame();
- handleDetectedComponentMouseEvents();
+ viewRepaintNeeded = renderingContext.handleDetectedComponentMouseEvents();
}
}
renderingContext = new RenderingContext(panelWidth, panelHeight);
}
- renderingContext.mouseEvent = null;
- renderingContext.objectUnderMouse = null;
+ renderingContext.prepareForNewFrameRendering();
}
private boolean notifyViewRenderListeners(int millisecondsPassedSinceLastUpdate) {
* @return <code>true</code> if view needs to be repainted.
*/
private synchronized boolean handleMouseClicksAndHover(final ViewPanel viewPanel) {
- MouseEvent mouseEventAndLocationToTrace = getMouseEventAndLocationToTrace(viewPanel);
- if (mouseEventAndLocationToTrace != null)
- {
- viewPanel.getRenderingContext().mouseEvent = mouseEventAndLocationToTrace;
- return true;
+ boolean rerenderNeeded = false;
+ MouseEvent event = findClickLocationToTrace();
+ if (event != null){
+ // process mouse clicks as a first priority
+ rerenderNeeded = true;
+ } else {
+ // when there are no mouse clicks, process mouse hovering
+
+ if (mouseMoved) {
+ mouseMoved = false;
+ // we would like to re-render frame when user moved mouse, to see what objects mouse is hovering over
+ rerenderNeeded = true;
+ }
+
+ if (currentMouseLocation != null) {
+ // mouse click with button 0 amounts to mouse hovering event
+ event = new MouseEvent(currentMouseLocation, 0);
+ }
}
- return false;
- }
- private MouseEvent getMouseEventAndLocationToTrace(ViewPanel viewPanel) {
- MouseEvent unprocessedMouseEvent = findClickLocationToTrace();
- if (unprocessedMouseEvent != null) {
- return unprocessedMouseEvent;
- } else
- return getHoverLocationToTrace(viewPanel);
+ if (viewPanel.getRenderingContext() != null)
+ viewPanel.getRenderingContext().setMouseEvent(event);
+
+ return rerenderNeeded;
}
private MouseEvent findClickLocationToTrace() {
}
}
- private MouseEvent getHoverLocationToTrace(ViewPanel viewPanel) {
- if (mouseMoved) {
- mouseMoved = false;
- if (currentMouseLocation != null) {
- return new MouseEvent(currentMouseLocation, 0);
- // mouse click with button 0 amounts to mouse hovering event
- }
- }
- return null;
- }
-
boolean isKeyPressed(final int keyCode) {
return pressedKeysToPressedTimeMap.containsKey(keyCode);
}
*/
public int button;
- public MouseEvent(final int x, final int y, final int button) {
+ MouseEvent(final int x, final int y, final int button) {
this(new Point2D(x, y), button);
}
- public MouseEvent(final Point2D coordinate, final int button) {
+ MouseEvent(final Point2D coordinate, final int button) {
this.coordinate = coordinate;
this.button = button;
}
+ @Override
+ public String toString() {
+ return "MouseEvent{" +
+ "coordinate=" + coordinate +
+ ", button=" + button +
+ '}';
+ }
}
public interface MouseInteractionController {
/**
- * Called when mouse is clicked on component
- * @return <code>true</code> if view update is needed.
+ * Called when mouse is clicked on component.
+ * @return <code>true</code> if view update is needed as a consequence of this mouse click.
*/
boolean mouseClicked();
/**
* Called when mouse gets over given component.
- * @return <code>true</code> if view update is needed.
+ * @return <code>true</code> if view update is needed as a consequence of this mouse enter.
*/
boolean mouseEntered();
/**
* Called when mouse leaves screen area occupied by component.
- * @return <code>true</code> if view update is needed.
+ * @return <code>true</code> if view update is needed as a consequence of this mouse exit.
*/
boolean mouseExited();
import eu.svjatoslav.sixth.e3d.geometry.Point2D;
import eu.svjatoslav.sixth.e3d.geometry.Point3D;
-import eu.svjatoslav.sixth.e3d.geometry.Polygon;
import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractCoordinateShape;
+import static eu.svjatoslav.sixth.e3d.geometry.Polygon.pointWithinPolygon;
+
public class SolidPolygon extends AbstractCoordinateShape {
private final static LineInterpolator polygonBoundary1 = new LineInterpolator();
onScreenPoint3.roundToInteger();
if (mouseInteractionController != null)
- if (context.mouseEvent != null)
- if (Polygon.pointWithinPolygon(context.mouseEvent.coordinate,
+ if (context.getMouseEvent() != null)
+ if (pointWithinPolygon(context.getMouseEvent().coordinate,
onScreenPoint1, onScreenPoint2, onScreenPoint3))
- context.objectUnderMouse = mouseInteractionController;
+ context.setObjectUnderMouse(mouseInteractionController);
if (color.isTransparent())
return;
projectedPoint3.roundToInteger();
if (mouseInteractionController != null)
- if (renderBuffer.mouseEvent != null)
+ if (renderBuffer.getMouseEvent() != null)
if (pointWithinPolygon(
- renderBuffer.mouseEvent.coordinate, projectedPoint1,
+ renderBuffer.getMouseEvent().coordinate, projectedPoint1,
projectedPoint2, projectedPoint3))
- renderBuffer.objectUnderMouse = mouseInteractionController;
+ renderBuffer.setObjectUnderMouse(mouseInteractionController);
// Show polygon boundaries (for debugging)
if (showBorders)