From b019a5e6ac11a08f2166603c9747cffd988099e4 Mon Sep 17 00:00:00 2001 From: Argent77 Date: Thu, 6 Mar 2014 17:52:38 +0100 Subject: [PATCH] Area viewer: Bugfixes and updates - bugfix in popup menu on ambient sound items - options to set frame rate for overlays and animations - added "Update map" option to toolbar --- .../resource/are/viewer/AreaViewer.java | 106 ++++++++++++------ .../resource/are/viewer/LayerAnimation.java | 31 +++++ .../resource/are/viewer/LayerManager.java | 50 ++++++--- .../resource/are/viewer/Settings.java | 48 +++++--- .../resource/are/viewer/SettingsDialog.java | 54 ++++++++- 5 files changed, 223 insertions(+), 66 deletions(-) diff --git a/src/infinity/resource/are/viewer/AreaViewer.java b/src/infinity/resource/are/viewer/AreaViewer.java index aef330bc0..ebab2e350 100644 --- a/src/infinity/resource/are/viewer/AreaViewer.java +++ b/src/infinity/resource/are/viewer/AreaViewer.java @@ -233,7 +233,6 @@ public void actionPerformed(ActionEvent event) } finally { WindowBlocker.blockWindow(this, false); } - WindowBlocker.blockWindow(this, false); } else if (cb == cbDrawClosed) { WindowBlocker.blockWindow(this, true); try { @@ -306,8 +305,12 @@ public void actionPerformed(ActionEvent event) } else if (event.getSource() == tbSettings) { viewSettings(); } else if (event.getSource() == tbRefresh) { - // TODO: add "Refresh map structures" functionality - JOptionPane.showMessageDialog(this, "Not yet implemented...", "Reload map structures", JOptionPane.INFORMATION_MESSAGE); + WindowBlocker.blockWindow(this, true); + try { + reloadLayers(); + } finally { + WindowBlocker.blockWindow(this, false); + } } else if (ArrayUtil.indexOf(tbAddLayerItem, event.getSource()) >= 0) { // TODO: include "Add layer item" functionality int index = ArrayUtil.indexOf(tbAddLayerItem, event.getSource()); @@ -912,7 +915,7 @@ private void init() tbRefresh = new JButton(Icons.getIcon("icn_refresh.png")); tbRefresh.setToolTipText("Update map"); tbRefresh.addActionListener(this); -// toolBar.add(tbRefresh); + toolBar.add(tbRefresh); updateToolBarButtons(); @@ -991,7 +994,7 @@ private void initGuiSettings() // initializing layers layerManager = new LayerManager(getCurrentAre(), getCurrentWed(), this); layerManager.setDoorState(Settings.DrawClosed ? ViewerConstants.DOOR_CLOSED : ViewerConstants.DOOR_OPEN); - layerManager.setScheduleEnabled(true); + layerManager.setScheduleEnabled(Settings.EnableSchedules); layerManager.setSchedule(LayerManager.toSchedule(getHour())); addLayerItems(); updateScheduledItems(); @@ -1047,6 +1050,8 @@ private void updateWindowTitle() dayNight = "day"; } + String scheduleState = Settings.EnableSchedules ? "enabled" : "disabled"; + String doorState = isDoorStateClosed() ? "closed" : "open"; String overlayState; @@ -1060,8 +1065,8 @@ private void updateWindowTitle() String gridState = isTileGridEnabled() ? "enabled" : "disabled"; - setTitle(String.format("%1$s (Time: %2$02d:00 (%3$s), Doors: %4$s, Overlays: %5$s, Grid: %6$s, Zoom: %7$d%%)", - windowTitle, getHour(), dayNight, doorState, overlayState, gridState, zoom)); + setTitle(String.format("%1$s (Time: %2$02d:00 (%3$s), Schedules: %4$s, Doors: %5$s, Overlays: %6$s, Grid: %7$s, Zoom: %8$d%%)", + windowTitle, getHour(), dayNight, scheduleState, doorState, overlayState, gridState, zoom)); } // Returns the general day time (day/twilight/night) @@ -1146,7 +1151,7 @@ private synchronized void setVisualState(int hour) } if (!rcCanvas.isMapLoaded() || rcCanvas.getWed() != map.getWed(Map.MAP_DAY)) { rcCanvas.loadMap(map.getWed(Map.MAP_DAY)); - reloadWedLayers(); + reloadWedLayers(true); } rcCanvas.setLighting(index); break; @@ -1156,7 +1161,7 @@ private synchronized void setVisualState(int hour) } if (!rcCanvas.isMapLoaded() || rcCanvas.getWed() != map.getWed(Map.MAP_DAY)) { rcCanvas.loadMap(map.getWed(Map.MAP_DAY)); - reloadWedLayers(); + reloadWedLayers(true); } rcCanvas.setLighting(index); break; @@ -1167,7 +1172,7 @@ private synchronized void setVisualState(int hour) if (!rcCanvas.isMapLoaded() || map.hasExtendedNight()) { if (rcCanvas.getWed() != map.getWed(Map.MAP_NIGHT)) { rcCanvas.loadMap(map.getWed(Map.MAP_NIGHT)); - reloadWedLayers(); + reloadWedLayers(true); } } if (!map.hasExtendedNight()) { @@ -1548,18 +1553,22 @@ private boolean updateItemPopup(Point canvasCoords) AbstractLayerItem[] items = itemList.get(j).getLayerItems(); // for each layer item... for (int k = 0; k < items.length; k++) { - // special case: Ambient/Ambient range (avoid duplicates) + // special case: Ambient/Ambient range (avoiding duplicates) if (stacking == LayerStackingType.Ambient && - isLayerEnabled(LayerStackingType.AmbientRange) && + cbLayerAmbientRange.isSelected() && ((LayerObjectAmbient)itemList.get(j)).isLocal()) { // skipped: will be handled in AmbientRange layer break; } - if (stacking == LayerStackingType.AmbientRange && - ((LayerObjectAmbient)itemList.get(j)).isLocal() && - k == ViewerConstants.AMBIENT_ITEM_ICON) { - // considering ranged item only - continue; + if (stacking == LayerStackingType.AmbientRange) { + if (((LayerObjectAmbient)itemList.get(j)).isLocal() && + k == ViewerConstants.AMBIENT_ITEM_ICON) { + // considering ranged item only + continue; + } else if (!((LayerObjectAmbient)itemList.get(j)).isLocal()) { + // global sounds don't have ambient ranges + break; + } } itemLocation.x = canvasCoords.x - items[k].getX(); itemLocation.y = canvasCoords.y - items[k].getY(); @@ -1631,33 +1640,45 @@ private void showItemPopup(MouseEvent event) // Updates all available layer items private void reloadLayers() { - reloadAreLayers(); - reloadWedLayers(); + reloadAreLayers(false); + reloadWedLayers(false); + orderLayerItems(); } // Updates ARE-related layer items - private void reloadAreLayers() + private void reloadAreLayers(boolean order) { if (layerManager != null) { - for (int i = 0; i < LayerStackingType.values().length; i++) { - LayerStackingType layer = LayerStackingType.values()[i]; - if (layer != LayerStackingType.DoorPoly && layer != LayerStackingType.WallPoly) { - removeLayerItems(layer); - layerManager.setAreResource(getCurrentAre()); - updateLayerItems(layer); - addLayerItems(layer); - if (layer != LayerStackingType.AmbientRange) { - showLayer(Settings.stackingToLayer(layer), cbLayers[i].isSelected()); +// layerManager.setAreResource(getCurrentAre()); + for (int i = 0; i < LayerManager.getLayerTypeCount(); i++) { + LayerType layer = LayerManager.getLayerType(i); + LayerStackingType layer2 = Settings.layerToStacking(layer); + if (layer != LayerType.DoorPoly && layer != LayerType.WallPoly) { + removeLayerItems(layer2); + if (layer == LayerType.Ambient) { + removeLayerItems(LayerStackingType.AmbientRange); + } + layerManager.reload(layer); + updateLayerItems(layer2); + addLayerItems(layer2); + if (layer == LayerType.Ambient) { + updateLayerItems(LayerStackingType.AmbientRange); + addLayerItems(LayerStackingType.AmbientRange); } + showLayer(layer, cbLayers[i].isSelected()); } } - updateAmbientRange(); - updateRealAnimation(); } + updateAmbientRange(); + updateRealAnimation(); + if (order) { + orderLayerItems(); + } + rcCanvas.repaint(); } // Updates WED-related layer items - private void reloadWedLayers() + private void reloadWedLayers(boolean order) { if (layerManager != null) { removeLayerItems(LayerStackingType.DoorPoly); @@ -1665,11 +1686,15 @@ private void reloadWedLayers() layerManager.setWedResource(getCurrentWed()); updateLayerItems(LayerStackingType.DoorPoly); addLayerItems(LayerStackingType.DoorPoly); - showLayer(LayerType.DoorPoly, cbLayers[LayerManager.getLayerTypeIndex(LayerType.DoorPoly)].isSelected()); updateLayerItems(LayerStackingType.WallPoly); addLayerItems(LayerStackingType.WallPoly); + showLayer(LayerType.DoorPoly, cbLayers[LayerManager.getLayerTypeIndex(LayerType.DoorPoly)].isSelected()); showLayer(LayerType.WallPoly, cbLayers[LayerManager.getLayerTypeIndex(LayerType.WallPoly)].isSelected()); } + if (order) { + orderLayerItems(); + } + rcCanvas.repaint(); } @@ -1769,11 +1794,11 @@ private Window getViewerWindow(AbstractStruct as) return NearInfinity.getInstance(); } - // Applying time schedule settings to layer items private void updateTimeSchedules() { layerManager.setScheduleEnabled(Settings.EnableSchedules); + updateWindowTitle(); } // Updates the state of the ambient sound range checkbox and associated functionality @@ -1953,14 +1978,16 @@ private void orderLayerItems() for (int j = 0; j < list.size(); j++) { if (Settings.ListLayerOrder.get(i) == LayerStackingType.AmbientRange) { // Special: process ambient ranges only - AbstractLayerItem item = list.get(j).getLayerItem(ViewerConstants.AMBIENT_ITEM_RANGE); + LayerObjectAmbient obj = (LayerObjectAmbient)list.get(j); + AbstractLayerItem item = obj.getLayerItem(ViewerConstants.AMBIENT_ITEM_RANGE); if (item != null) { rcCanvas.setComponentZOrder(item, index); index++; } } else if (Settings.ListLayerOrder.get(i) == LayerStackingType.Ambient) { // Special: process ambient icons only - AbstractLayerItem item = list.get(j).getLayerItem(ViewerConstants.AMBIENT_ITEM_ICON); + LayerObjectAmbient obj = (LayerObjectAmbient)list.get(j); + AbstractLayerItem item = obj.getLayerItem(ViewerConstants.AMBIENT_ITEM_ICON); rcCanvas.setComponentZOrder(item, index); index++; } else { @@ -2096,6 +2123,13 @@ private void applySettings() layerManager.setRealAnimationInterpolation(ViewerConstants.TYPE_NEAREST_NEIGHBOR); break; } + // applying frame rate to animated overlays + int interval = (int)(1000.0 / Settings.FrameRateOverlays); + if (interval != timerOverlays.getDelay()) { + timerOverlays.setDelay(interval); + } + // applying frame rate to background animations + layerManager.setRealAnimationFrameRate(Settings.FrameRateAnimations); } } diff --git a/src/infinity/resource/are/viewer/LayerAnimation.java b/src/infinity/resource/are/viewer/LayerAnimation.java index 618845b13..ed8220f52 100644 --- a/src/infinity/resource/are/viewer/LayerAnimation.java +++ b/src/infinity/resource/are/viewer/LayerAnimation.java @@ -25,6 +25,7 @@ public class LayerAnimation extends BasicLayer private boolean realEnabled, realPlaying, forcedInterpolation; private int frameState, interpolationType; + private double frameRate; public LayerAnimation(AreResource are, AreaViewer viewer) { @@ -238,6 +239,36 @@ public void setRealAnimationFrameState(int state) } } + /** + * Returns the frame rate used for playing back background animations. + * @return Frame rate in frames/second. + */ + public double getRealAnimationFrameRate() + { + return frameRate; + } + + /** + * Specify a new frame rate for real animations. + * @param frameRate Frame rate in frames/second. + */ + public void setRealAnimationFrameRate(double frameRate) + { + frameRate = Math.min(Math.max(frameRate, 1.0), 30.0); + if (frameRate != this.frameRate) { + this.frameRate = frameRate; + List list = getLayerObjects(); + if (list != null) { + for (int i = 0; i < list.size(); i++) { + AnimatedLayerItem item = (AnimatedLayerItem)list.get(i).getLayerItem(ViewerConstants.ANIM_ITEM_REAL); + if (item != null) { + item.setFrameRate(this.frameRate); + } + } + } + } + } + private void updateFrameState() { List list = getLayerObjects(); diff --git a/src/infinity/resource/are/viewer/LayerManager.java b/src/infinity/resource/are/viewer/LayerManager.java index d30d6f9d2..ecaaa4abf 100644 --- a/src/infinity/resource/are/viewer/LayerManager.java +++ b/src/infinity/resource/are/viewer/LayerManager.java @@ -16,10 +16,6 @@ * Manages all layer objects of a single ARE map. * @author argent77 */ -/* - * TODO: add interpolation type support for animations - * TODO: add update layer item methods for all layers - */ public final class LayerManager { // Defines order of drawing @@ -66,8 +62,9 @@ public final class LayerManager private AreResource are; private WedResource wed; - private boolean scheduleEnabled, forcedInterpolation; - private int schedule, interpolationType; + private boolean scheduleEnabled, animForcedInterpolation; + private int schedule, animInterpolationType; + private double animFrameRate; /** * Returns the number of supported layer types. @@ -463,7 +460,7 @@ public void setRealAnimationPlaying(boolean play) */ public int getRealAnimationInterpolation() { - return interpolationType; + return animInterpolationType; } /** @@ -477,11 +474,11 @@ public void setRealAnimationInterpolation(int interpolationType) case ViewerConstants.TYPE_NEAREST_NEIGHBOR: case ViewerConstants.TYPE_BILINEAR: case ViewerConstants.TYPE_BICUBIC: - if (interpolationType != this.interpolationType) { - this.interpolationType = interpolationType; + if (interpolationType != animInterpolationType) { + animInterpolationType = interpolationType; LayerAnimation layer = (LayerAnimation)getLayer(LayerType.Animation); if (layer != null) { - layer.setRealAnimationInterpolation(this.interpolationType); + layer.setRealAnimationInterpolation(animInterpolationType); } } } @@ -493,7 +490,7 @@ public void setRealAnimationInterpolation(int interpolationType) */ public boolean isRealAnimationForcedInterpolation() { - return forcedInterpolation; + return animForcedInterpolation; } /** @@ -502,11 +499,36 @@ public boolean isRealAnimationForcedInterpolation() */ public void setRealAnimationForcedInterpolation(boolean forced) { - if (forced != forcedInterpolation) { - forcedInterpolation = forced; + if (forced != animForcedInterpolation) { + animForcedInterpolation = forced; + LayerAnimation layer = (LayerAnimation)getLayer(LayerType.Animation); + if (layer != null) { + layer.setRealAnimationForcedInterpolation(animForcedInterpolation); + } + } + } + + /** + * Returns the frame rate used for playing back background animations. + * @return Frame rate in frames/second. + */ + public double getRealAnimationFrameRate() + { + return animFrameRate; + } + + /** + * Specify a new frame rate for background animations. + * @param frameRate Frame rate in frames/second. + */ + public void setRealAnimationFrameRate(double frameRate) + { + frameRate = Math.min(Math.max(frameRate, 1.0), 30.0); + if (frameRate != this.animFrameRate) { + animFrameRate = frameRate; LayerAnimation layer = (LayerAnimation)getLayer(LayerType.Animation); if (layer != null) { - layer.setRealAnimationForcedInterpolation(forcedInterpolation); + layer.setRealAnimationFrameRate(animFrameRate); } } } diff --git a/src/infinity/resource/are/viewer/Settings.java b/src/infinity/resource/are/viewer/Settings.java index dae181579..767329f51 100644 --- a/src/infinity/resource/are/viewer/Settings.java +++ b/src/infinity/resource/are/viewer/Settings.java @@ -67,22 +67,28 @@ public class Settings public static int TimeOfDay = getDefaultTimeOfDay(); // The current zoom level of the map (as combobox item index) public static int ZoomLevel = getDefaultZoomLevel(); + // The frame rate for animated overlays + public static double FrameRateOverlays = getDefaultFrameRateOverlays(); + // The frame rate for animated background animations + public static double FrameRateAnimations = getDefaultFrameRateAnimations(); // Preferences keys for specific settings - private static final String PREFS_STORESETTINGS = "StoreSettings"; - private static final String PREFS_DRAWCLOSED = "DrawClosed"; - private static final String PREFS_DRAWOVERLAYS = "DrawOverlays"; - private static final String PREFS_DRAWGRID = "DrawGrid"; - private static final String PREFS_SHOWFRAME = "ShowFrame"; - private static final String PREFS_SHOWAMBIENT = "ShowAmbientRanges"; - private static final String PREFS_ENABLESCHEDULES = "EnableSchedules"; - private static final String PREFS_LAYERFLAGS = "LayerFlags"; - private static final String PREFS_SHOWREALANIMS = "ShowRealAnimations"; - private static final String PREFS_TIMEOFDAY = "TimeOfDay"; - private static final String PREFS_ZOOMLEVEL = "ZoomLevel"; - private static final String PREFS_LAYERZORDER_FMT = "LayerZOrder%1$d"; - private static final String PREFS_INTERPOLATION_MAP = "InterpolationMap"; + private static final String PREFS_STORESETTINGS = "StoreSettings"; + private static final String PREFS_DRAWCLOSED = "DrawClosed"; + private static final String PREFS_DRAWOVERLAYS = "DrawOverlays"; + private static final String PREFS_DRAWGRID = "DrawGrid"; + private static final String PREFS_SHOWFRAME = "ShowFrame"; + private static final String PREFS_SHOWAMBIENT = "ShowAmbientRanges"; + private static final String PREFS_ENABLESCHEDULES = "EnableSchedules"; + private static final String PREFS_LAYERFLAGS = "LayerFlags"; + private static final String PREFS_SHOWREALANIMS = "ShowRealAnimations"; + private static final String PREFS_TIMEOFDAY = "TimeOfDay"; + private static final String PREFS_ZOOMLEVEL = "ZoomLevel"; + private static final String PREFS_LAYERZORDER_FMT = "LayerZOrder%1$d"; + private static final String PREFS_INTERPOLATION_MAP = "InterpolationMap"; private static final String PREFS_INTERPOLATION_ANIMS = "InterpolationAnims"; + private static final String PREFS_FRAMERATE_OVERLAYS = "FrameRateOverlays"; + private static final String PREFS_FRAMERATE_ANIMS = "FrameRateAnims"; private static boolean SettingsLoaded = false; @@ -100,6 +106,8 @@ public static void loadSettings(boolean force) ShowFrame = prefs.getInt(PREFS_SHOWFRAME, getDefaultShowFrame()); InterpolationMap = prefs.getInt(PREFS_INTERPOLATION_MAP, getDefaultInterpolationMap()); InterpolationAnim = prefs.getInt(PREFS_INTERPOLATION_ANIMS, getDefaultInterpolationAnim()); + FrameRateOverlays = prefs.getDouble(PREFS_FRAMERATE_OVERLAYS, getDefaultFrameRateOverlays()); + FrameRateAnimations = prefs.getDouble(PREFS_FRAMERATE_ANIMS, getDefaultFrameRateAnimations()); // loading layer z-order ListLayerOrder.clear(); @@ -143,6 +151,8 @@ public static void storeSettings(boolean force) prefs.putInt(PREFS_SHOWFRAME, ShowFrame); prefs.putInt(PREFS_INTERPOLATION_MAP, InterpolationMap); prefs.putInt(PREFS_INTERPOLATION_ANIMS, InterpolationAnim); + prefs.putDouble(PREFS_FRAMERATE_OVERLAYS, FrameRateOverlays); + prefs.putDouble(PREFS_FRAMERATE_ANIMS, FrameRateAnimations); // storing layer z-order for (int i = 0; i < ListLayerOrder.size(); i++) { @@ -182,6 +192,8 @@ private static void validateSettings() ViewerConstants.INTERPOLATION_BILINEAR); InterpolationAnim = Math.min(Math.max(InterpolationAnim, ViewerConstants.INTERPOLATION_AUTO), ViewerConstants.INTERPOLATION_BILINEAR); + FrameRateOverlays = Math.min(Math.max(FrameRateOverlays, 1.0), 30.0); + FrameRateAnimations = Math.min(Math.max(FrameRateAnimations, 1.0), 30.0); // validating layers z-order mask = 0; @@ -280,6 +292,16 @@ public static int getDefaultZoomLevel() return ZoomFactorIndexDefault; } + public static double getDefaultFrameRateOverlays() + { + return 7.5; + } + + public static double getDefaultFrameRateAnimations() + { + return 15.0; + } + // Converts values from LayerStackingType to LayerType public static LayerType stackingToLayer(LayerStackingType type) { diff --git a/src/infinity/resource/are/viewer/SettingsDialog.java b/src/infinity/resource/are/viewer/SettingsDialog.java index c78587e8f..4f9f5d185 100644 --- a/src/infinity/resource/are/viewer/SettingsDialog.java +++ b/src/infinity/resource/are/viewer/SettingsDialog.java @@ -34,9 +34,11 @@ import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JRadioButton; +import javax.swing.JSpinner; import javax.swing.JTextArea; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; +import javax.swing.SpinnerNumberModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; @@ -63,6 +65,7 @@ public class SettingsDialog extends JDialog implements ActionListener, ListSelec private JComboBox cbQualityMap, cbQualityAnim; private JCheckBox cbStoreSettings; private JButton bDefaultSettings, bCancel, bOK; + private JSpinner sOverlaysFps, sAnimationsFps; private boolean settingsChanged; public SettingsDialog(Window owner) @@ -131,6 +134,9 @@ private void updateSettings() Settings.InterpolationMap = cbQualityMap.getSelectedIndex(); Settings.InterpolationAnim = cbQualityAnim.getSelectedIndex(); + Settings.FrameRateOverlays = (Double)sOverlaysFps.getValue(); + Settings.FrameRateAnimations = (Double)sAnimationsFps.getValue(); + Settings.StoreVisualSettings = cbStoreSettings.isSelected(); settingsChanged = true; @@ -164,6 +170,9 @@ private void resetDialogSettings() cbQualityMap.setSelectedIndex(Settings.getDefaultInterpolationMap()); cbQualityAnim.setSelectedIndex(Settings.getDefaultInterpolationAnim()); + sOverlaysFps.setValue(Double.valueOf(Settings.getDefaultFrameRateOverlays())); + sAnimationsFps.setValue(Double.valueOf(Settings.getDefaultFrameRateAnimations())); + cbStoreSettings.setSelected(Settings.getDefaultStoreVisualSettings()); } @@ -235,7 +244,6 @@ private void init() taOrderNote.setSelectionColor(lDummy.getBackground()); taOrderNote.setSelectedTextColor(lDummy.getForeground()); taOrderNote.setText("Note: Layers of higher priority are drawn on top of layers of lower priority."); - lDummy = null; JPanel pLayersArrows = new JPanel(new GridBagLayout()); bUp = new JButton(Icons.getIcon("Up16.gif")); @@ -321,6 +329,43 @@ private void init() GridBagConstraints.HORIZONTAL, new Insets(4, 4, 4, 4), 0, 0); pQuality.add(cbQualityAnim, c); + // Frame rates + JPanel pFrameRates = new JPanel(new GridBagLayout()); + pFrameRates.setBorder(BorderFactory.createTitledBorder("Frame rates: ")); + JTextArea taFrameRatesNote = new JTextArea(); + taFrameRatesNote.setEditable(false); + taFrameRatesNote.setWrapStyleWord(true); + taFrameRatesNote.setLineWrap(true); + taFrameRatesNote.setFont(lDummy.getFont()); + taFrameRatesNote.setBackground(lDummy.getBackground()); + taFrameRatesNote.setSelectionColor(lDummy.getBackground()); + taFrameRatesNote.setSelectedTextColor(lDummy.getForeground()); + taFrameRatesNote.setText("Caution: The area viewer may become less responsive on higher frame rates."); + + sOverlaysFps = new JSpinner(new SpinnerNumberModel(Settings.FrameRateOverlays, 1.0, 30.0, 0.5)); + sAnimationsFps = new JSpinner(new SpinnerNumberModel(Settings.FrameRateAnimations, 1.0, 30.0, 0.5)); + c = setGBC(c, 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, + GridBagConstraints.NONE, new Insets(0, 4, 4, 0), 0, 0); + pFrameRates.add(new JLabel("Overlays:"), c); + c = setGBC(c, 1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, + GridBagConstraints.NONE, new Insets(0, 8, 4, 0), 0, 0); + pFrameRates.add(sOverlaysFps, c); + c = setGBC(c, 2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, + GridBagConstraints.NONE, new Insets(0, 4, 4, 0), 0, 0); + pFrameRates.add(new JLabel("fps"), c); + c = setGBC(c, 3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, + GridBagConstraints.NONE, new Insets(0, 16, 4, 0), 0, 0); + pFrameRates.add(new JLabel("Animations:"), c); + c = setGBC(c, 4, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, + GridBagConstraints.NONE, new Insets(0, 8, 4, 0), 0, 0); + pFrameRates.add(sAnimationsFps, c); + c = setGBC(c, 5, 0, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, + GridBagConstraints.NONE, new Insets(0, 4, 4, 4), 0, 0); + pFrameRates.add(new JLabel("fps"), c); + c = setGBC(c, 0, 1, 6, 1, 1.0, 0.0, GridBagConstraints.LINE_START, + GridBagConstraints.HORIZONTAL, new Insets(4, 4, 4, 4), 0, 0); + pFrameRates.add(taFrameRatesNote, c); + // Misc. settings JPanel pMisc = new JPanel(new GridBagLayout()); pMisc.setBorder(BorderFactory.createTitledBorder("Misc. settings: ")); @@ -359,11 +404,14 @@ private void init() pOptions.add(pQuality, c); c = setGBC(c, 0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(4, 0, 0, 0), 0, 0); + pOptions.add(pFrameRates, c); + c = setGBC(c, 0, 3, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, + GridBagConstraints.HORIZONTAL, new Insets(4, 0, 0, 0), 0, 0); pOptions.add(pMisc, c); - c = setGBC(c, 0, 3, 1, 1, 1.0, 1.0, GridBagConstraints.LINE_START, + c = setGBC(c, 0, 4, 1, 1, 1.0, 1.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0); pOptions.add(new JPanel(), c); - c = setGBC(c, 0, 4, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, + c = setGBC(c, 0, 5, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0); pOptions.add(pButtons, c);