package eu.svjatoslav.sixth.e3d.gui;
+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.gui.humaninput.HIDInputTracker;
import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Set;
import java.util.Timer;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Java Swing GUI panel that contains canvas for 3D rendering.
private static final long serialVersionUID = 1683277888885045387L;
public Color backgroundColor = Color.BLACK;
private final HIDInputTracker HIDInputTracker = new HIDInputTracker(this);
- private final KeyboardFocusStack keyboardFocusStack = new KeyboardFocusStack(this);
+ private final KeyboardFocusStack keyboardFocusStack;
private final Avatar avatar = new Avatar();
private final ShapeCollection rootShapeCollection = new ShapeCollection();
- private final List<ViewRenderListener> viewRenderListeners = new ArrayList<>();
+ private final Set<ViewRenderListener> viewRenderListeners = ConcurrentHashMap.newKeySet();
/**
* Last time this view was updated.
*/
viewRenderListeners.add(avatar);
viewRenderListeners.add(HIDInputTracker);
+ keyboardFocusStack = new KeyboardFocusStack(this);
+
initializePanelLayout();
setFrameRate(targetFPS);
}
private void handleDetectedComponentMouseEvents() {
- if (renderingContext.clickedItem != null) {
- if (renderingContext.mouseClick.button == 0) {
+ if (renderingContext.objectUnderMouse != null) {
+ if (renderingContext.mouseEvent.button == 0) {
// mouse over
if (currentMouseOverComponent == null) {
- currentMouseOverComponent = renderingContext.clickedItem;
- currentMouseOverComponent.mouseEntered();
- viewRepaintNeeded = true;
- } else if (currentMouseOverComponent != renderingContext.clickedItem) {
- currentMouseOverComponent.mouseExited();
- currentMouseOverComponent = renderingContext.clickedItem;
- currentMouseOverComponent.mouseEntered();
- viewRepaintNeeded = true;
+ currentMouseOverComponent = renderingContext.objectUnderMouse;
+ viewRepaintNeeded |= currentMouseOverComponent.mouseEntered();
+ } else if (currentMouseOverComponent != renderingContext.objectUnderMouse) {
+ viewRepaintNeeded |= currentMouseOverComponent.mouseExited();
+ currentMouseOverComponent = renderingContext.objectUnderMouse;
+ viewRepaintNeeded |= currentMouseOverComponent.mouseEntered();
}
} else {
// mouse click
- renderingContext.clickedItem.mouseClicked();
- viewRepaintNeeded = true;
+ viewRepaintNeeded |= renderingContext.objectUnderMouse.mouseClicked();
}
} else if (currentMouseOverComponent != null) {
- currentMouseOverComponent.mouseExited();
- viewRepaintNeeded = true;
+ viewRepaintNeeded |= currentMouseOverComponent.mouseExited();
currentMouseOverComponent = null;
}
}
}
private void renderFrame() {
- if (isNewRenderingContextNeeded())
- renderingContext = new RenderingContext(getWidth(), getHeight());
// paint root geometry collection to the offscreen render buffer
clearCanvas();
renderingContext.graphics.fillRect(0, 0, getWidth(), getHeight());
}
- private boolean isNewRenderingContextNeeded() {
- return (renderingContext == null)
- || (renderingContext.width != getWidth())
- || (renderingContext.height != getHeight());
- }
-
/**
* Calling this methods tells 3D engine that current 3D view needs to be
* repainted on first opportunity.
* graphics is needed.
*/
void updateView() {
- if (renderingContext != null) {
- renderingContext.mouseClick = null;
- renderingContext.clickedItem = null;
- }
+ maintainRenderingContext();
final int millisecondsPassedSinceLastUpdate = getMillisecondsPassedSinceLastUpdate();
}
// abort rendering if window size is invalid
- if ((getWidth() <= 0) || (getHeight() <= 0))
- renderFrame = false;
-
- if (renderFrame) {
+ if ((getWidth() > 0) && (getHeight() > 0) && renderFrame) {
renderFrame();
handleDetectedComponentMouseEvents();
}
+
+ }
+
+ private void maintainRenderingContext() {
+ int panelWidth = getWidth();
+ int panelHeight = getHeight();
+
+ if (panelWidth <= 0 || panelHeight <=0){
+ renderingContext = null;
+ return;
+ }
+
+ if ((renderingContext == null)
+ || (renderingContext.width != panelWidth)
+ || (renderingContext.height != panelHeight)) {
+ renderingContext = new RenderingContext(panelWidth, panelHeight);
+ }
+
+ renderingContext.mouseEvent = null;
+ renderingContext.objectUnderMouse = null;
}
private boolean notifyViewRenderListeners(int millisecondsPassedSinceLastUpdate) {
lastUpdateMillis = currentTime;
return millisecondsPassedSinceLastUpdate;
}
+
+ public void addViewRenderListener(ViewRenderListener viewRenderListener) {
+ viewRenderListeners.add(viewRenderListener);
+ }
+
+ public void removeViewRenderListener(ViewRenderListener viewRenderListener) {
+ viewRenderListeners.remove(viewRenderListener);
+ }
+
}