Updated readability of the code.
[sixth-3d.git] / src / main / java / eu / svjatoslav / sixth / e3d / gui / RenderingContext.java
1 /*
2  * Sixth 3D engine. Author: Svjatoslav Agejenko. 
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5 package eu.svjatoslav.sixth.e3d.gui;
6
7 import eu.svjatoslav.sixth.e3d.geometry.Point2D;
8 import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseEvent;
9 import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
10
11 import java.awt.*;
12 import java.awt.image.BufferedImage;
13 import java.awt.image.DataBufferByte;
14 import java.awt.image.WritableRaster;
15
16 public class RenderingContext {
17
18     public static final int bufferedImageType = BufferedImage.TYPE_4BYTE_ABGR;
19     public final Graphics2D graphics;
20     public final byte[] pixels;
21     public final int width;
22     public final int height;
23     /**
24      * Center of the screen in screen space (pixels).
25      * This is the point where (0,0) coordinate of the world space is rendered.
26      */
27     public final Point2D centerCoordinate;
28
29     /**
30      * Zoom factor. The bigger the value, the more zoomed in the view is.
31      */
32     public final double zoom;
33     final BufferedImage bufferedImage;
34     /**
35      * Number of frame that is currently being rendered.
36      * Every frame has its own number.
37      */
38     public int frameNumber = 0;
39
40     /**
41      * UI component that mouse is currently hovering over.
42      */
43     private MouseInteractionController objectPreviouslyUnderMouseCursor;
44
45     public void prepareForNewFrameRendering(){
46         mouseEvent = null;
47         currentObjectUnderMouseCursor = null;
48     }
49
50     /**
51      * Mouse click event that needs to be processed.
52      * This event is processed only once per frame.
53      * If there are multiple objects under mouse cursor, the top-most object will receive the event.
54      * If there are no objects under mouse cursor, the event will be ignored.
55      * If there is no event, this field will be null.
56      * This field is set to null after the event is processed.
57      */
58     private MouseEvent mouseEvent;
59
60     public void setMouseEvent(MouseEvent mouseEvent) {
61         this.mouseEvent = mouseEvent;
62     }
63
64     public MouseEvent getMouseEvent() {
65         return mouseEvent;
66     }
67
68     /**
69      * UI component that mouse is currently hovering over.
70      */
71     private MouseInteractionController currentObjectUnderMouseCursor;
72
73     /**
74      * Called when given object was detected under mouse cursor, while processing {@link #mouseEvent}.
75      * Because objects are rendered back to front. The last method caller will set the top-most object, if
76      * there are multiple objects under mouse cursor.
77      */
78     public void setCurrentObjectUnderMouseCursor(MouseInteractionController currentObjectUnderMouseCursor) {
79         this.currentObjectUnderMouseCursor = currentObjectUnderMouseCursor;
80     }
81
82     public RenderingContext(final int width, final int height) {
83         this.width = width;
84         this.height = height;
85         this.centerCoordinate = new Point2D(width / 2d, height / 2d);
86         this.zoom = width / 3d;
87
88         bufferedImage = new BufferedImage(width, height, bufferedImageType);
89
90         final WritableRaster raster = bufferedImage.getRaster();
91         final DataBufferByte dbi = (DataBufferByte) raster.getDataBuffer();
92         pixels = dbi.getData();
93
94         graphics = (Graphics2D) bufferedImage.getGraphics();
95         graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
96         graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
97     }
98
99     /**
100      * @return <code>true</code> if view update is needed as a consequence of this mouse event.
101      */
102     public boolean handlePossibleComponentMouseEvent() {
103         if (mouseEvent == null) return false;
104
105         boolean viewRepaintNeeded = false;
106
107         if (objectPreviouslyUnderMouseCursor != currentObjectUnderMouseCursor) {
108             // Mouse cursor has just entered or left component.
109             viewRepaintNeeded = objectPreviouslyUnderMouseCursor != null && objectPreviouslyUnderMouseCursor.mouseExited();
110             viewRepaintNeeded |= currentObjectUnderMouseCursor != null && currentObjectUnderMouseCursor.mouseEntered();
111             objectPreviouslyUnderMouseCursor = currentObjectUnderMouseCursor;
112         }
113
114         if (mouseEvent.button != 0 && currentObjectUnderMouseCursor != null) {
115             // Mouse button was clicked on some component.
116             viewRepaintNeeded |= currentObjectUnderMouseCursor.mouseClicked(mouseEvent.button);
117         }
118
119         return viewRepaintNeeded;
120     }
121
122 }