44import java .awt .geom .*;
55import java .awt .image .BufferedImage ;
66import java .text .DecimalFormat ;
7+ import java .util .prefs .Preferences ;
78
89import javax .swing .*;
910
1011import com .modsim .modules .BaseModule ;
1112import com .modsim .modules .Link ;
13+ import com .modsim .modules .parts .VisiblePart ;
1214import com .modsim .res .Colors ;
1315import com .modsim .Main ;
1416import com .modsim .tools .BaseTool ;
@@ -38,10 +40,16 @@ public class View extends JPanel {
3840
3941 public boolean useAA = true ;
4042
43+ private int dynamicRefreshRate = 30 ;
44+
4145 private BufferedImage staticCanvas = null ;
4246 private boolean staticIsDirty = true ;
4347 private long lastDynamicPaint = 0 ;
4448
49+ // Zoom caps
50+ public static final double minZoom = 0.01 ;
51+ public static final double maxZoom = 6.0 ;
52+
4553 public View () {
4654 setFocusable (true );
4755 ViewUtil listener = new ViewUtil ();
@@ -50,7 +58,32 @@ public View() {
5058 addMouseWheelListener (listener );
5159 addKeyListener (listener );
5260
53- //staticCanvas = getGraphicsConfiguration().createCompatibleImage(800, 600);
61+ // Fetch the preferred refresh rate
62+ Preferences prefs = Preferences .userNodeForPackage (View .class );
63+ dynamicRefreshRate = prefs .getInt ("dynamic_refresh_rate" , dynamicRefreshRate );
64+ }
65+
66+ /***
67+ * @return The current dynamic refresh rate
68+ */
69+ public int getDynamicRefreshRate () {
70+ return dynamicRefreshRate ;
71+ }
72+
73+ /***
74+ * Sets and stores the dynamic refresh rate for the view. Capped to 5-120Hz
75+ * @param newRate The new refresh rate, in Hz
76+ */
77+ public void setDynamicRefreshRate (int newRate ) {
78+ if (newRate < 5 ) {
79+ newRate = 5 ;
80+ }
81+ else if (newRate > 120 ) {
82+ newRate = 120 ;
83+ }
84+ Preferences prefs = Preferences .userNodeForPackage (View .class );
85+ dynamicRefreshRate = newRate ;
86+ prefs .putInt ("dynamic_refresh_rate" , newRate );
5487 }
5588
5689 public void calcXForm () {
@@ -192,9 +225,9 @@ public void paintComponent(Graphics oldG) {
192225 }
193226
194227 /**
195- * Draws an error flag
228+ * Draws a module's error flag
196229 */
197- public void drawError (Graphics2D g ) {
230+ private void drawError (Graphics2D g ) {
198231 g .setColor (Colors .errorEdge );
199232 g .drawOval (-30 , -30 , 60 , 60 );
200233 g .setColor (Colors .errorFill );
@@ -205,27 +238,32 @@ public void drawError(Graphics2D g) {
205238 }
206239
207240 /**
208- * Draws a grid
241+ * Draws the background grid
209242 */
210- public void drawGrid (Graphics2D g ) {
243+ private void drawGrid (Graphics2D g ) {
211244 double grid = zoom * Main .sim .grid ;
212245
246+ // When extremely zoomed-out, displaying the grid is costly and pointless
247+ if (grid < 1.5 ) {
248+ return ;
249+ }
250+
213251 int xNum = (int )(getWidth () / grid );
214252 int yNum = (int )(getHeight () / grid );
215253
216- AffineTransform oldxform = new AffineTransform (g .getTransform ());
254+ AffineTransform oldTransform = new AffineTransform (g .getTransform ());
217255 Line2D verticalLine = new Line2D .Double (0.0 , -grid , 0.0 , getHeight () + grid );
218256 Line2D horizontalLine = new Line2D .Double (-grid , 0.0 , getWidth () + grid , 0.0 );
219257 for (int i = 0 ; i <= xNum + 1 ; i ++) {
220258 g .draw (verticalLine );
221259 g .translate (grid , 0.0 );
222260 }
223- g .setTransform (oldxform );
261+ g .setTransform (oldTransform );
224262 for (int i = 0 ; i <= yNum + 1 ; i ++) {
225263 g .draw (horizontalLine );
226264 g .translate (0.0 , grid );
227265 }
228- g .setTransform (oldxform );
266+ g .setTransform (oldTransform );
229267 }
230268
231269 /**
@@ -254,45 +292,25 @@ public void setTool(BaseTool newTool) {
254292 }
255293
256294 /**
257- * Zooms the viewport in on the specified screen point
295+ * Smoothly zooms the viewport in or out of the specified screen point
258296 * @param x X-coordinate
259297 * @param y Y-coordinate
260298 */
261- public void zoomIn (int x , int y ) {
299+ public void zoom (int x , int y , double amount ) {
262300 Vec2 zmPt = ViewUtil .screenToWorld (new Vec2 (x , y ));
263301
264- zoomI ++ ;
265- if (zoomI > ZOOM_LIMIT ) {
266- zoomI -- ;
302+ zoom -= zoom * amount * ZOOM_MULTIPLIER ;
303+ if (zoom < minZoom ) {
304+ zoom = minZoom ;
267305 }
268- else {
269- zoom = zoomI * ZOOM_MULTIPLIER ;
270- calcXForm ();
271- Vec2 newScreenPt = ViewUtil .worldToScreen (zmPt );
272- camX -= newScreenPt .x - x ;
273- camY -= newScreenPt .y - y ;
274- }
275- }
276-
277- /**
278- * Zooms the view out form the specified screen point
279- * @param x X-coordinate
280- * @param y Y-coordinate
281- */
282- public void zoomOut (int x , int y ) {
283- Vec2 zmPt = ViewUtil .screenToWorld (new Vec2 (x , y ));
284-
285- zoomI --;
286- if (zoomI < 1 ) {
287- zoomI = 1 ;
288- }
289- else {
290- zoom = zoomI * ZOOM_MULTIPLIER ;
291- calcXForm ();
292- Vec2 newScreenPt = ViewUtil .worldToScreen (zmPt );
293- camX -= newScreenPt .x - x ;
294- camY -= newScreenPt .y - y ;
306+ else if (zoom > maxZoom ) {
307+ zoom = maxZoom ;
295308 }
309+ calcXForm ();
310+ Vec2 newScreenPt = ViewUtil .worldToScreen (zmPt );
311+ camX -= newScreenPt .x - x ;
312+ camY -= newScreenPt .y - y ;
313+ calcXForm ();
296314 }
297315
298316 /***
@@ -308,12 +326,16 @@ public void flagStaticRedraw() {
308326 */
309327 public void flagDynamicRedraw () {
310328 long currentTime = System .currentTimeMillis ();
311- if (abs (currentTime - lastDynamicPaint ) > 33 ) {
329+ if (abs (currentTime - lastDynamicPaint ) > ( 1000 / dynamicRefreshRate ) ) {
312330 repaint ();
313331 }
314332 else {
315333 // persistence-of-vision simulation
316- // TODO!!
334+ for (BaseModule m : Main .sim .getModules ()) {
335+ for (VisiblePart p : m .parts ) {
336+ p .povTick ();
337+ }
338+ }
317339 }
318340 }
319341}
0 commit comments