diff --git a/src/whitehole/MainFrame.form b/src/whitehole/MainFrame.form index 4f19ef7..e019925 100644 --- a/src/whitehole/MainFrame.form +++ b/src/whitehole/MainFrame.form @@ -136,9 +136,6 @@ - - - diff --git a/src/whitehole/MainFrame.java b/src/whitehole/MainFrame.java index d015333..aec0fd4 100644 --- a/src/whitehole/MainFrame.java +++ b/src/whitehole/MainFrame.java @@ -290,7 +290,7 @@ private void btnBcsvEditorActionPerformed(java.awt.event.ActionEvent evt) {//GEN }//GEN-LAST:event_btnBcsvEditorActionPerformed private void btnSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSettingsActionPerformed - new SettingsForm().setVisible(true); + new SettingsForm(this).setVisible(true); }//GEN-LAST:event_btnSettingsActionPerformed private void btnAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAboutActionPerformed @@ -312,7 +312,7 @@ private void listGalaxyKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:eve return; } - if(evt.getKeyCode() == KeyEvent.VK_ENTER) { + if (evt.getKeyCode() == KeyEvent.VK_ENTER) { openGalaxy(); } }//GEN-LAST:event_listGalaxyKeyReleased @@ -327,7 +327,7 @@ private void listGalaxyKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:eve private javax.swing.JToolBar.Separator jSeparator2; private javax.swing.JToolBar.Separator jSeparator3; private javax.swing.JToolBar.Separator jSeparator6; - public static javax.swing.JLabel lbStatusBar; + private javax.swing.JLabel lbStatusBar; private javax.swing.JList listGalaxy; private javax.swing.JScrollPane scrGalaxy; private javax.swing.JToolBar toolbar; diff --git a/src/whitehole/Settings.java b/src/whitehole/Settings.java index 326cc8a..b97a12d 100644 --- a/src/whitehole/Settings.java +++ b/src/whitehole/Settings.java @@ -28,10 +28,12 @@ private Settings() {} public static String getLastGameDir() { return PREFERENCES.get("whitehole_lastGameDir", null); } public static boolean getSJISNotSupported() { return PREFERENCES.getBoolean("whitehole_sjisNotSupported", false); } public static boolean getDisplaySimpleNameDB() { return PREFERENCES.getBoolean("whitehole_displaySimpleNameDB", true); } + public static boolean getUseDarkMode() { return PREFERENCES.getBoolean("whitehole_useDarkMode", true); } public static void setLastGameDir(String val) { PREFERENCES.put("whitehole_lastGameDir", val); } public static void setSJISNotSupported(boolean val) { PREFERENCES.putBoolean("whitehole_sjisNotSupported", val); } public static void setDisplaySimpleNameDB(boolean val) { PREFERENCES.putBoolean("whitehole_displaySimpleNameDB", val); } + public static void setUseDarkMode(boolean val) { PREFERENCES.putBoolean("whitehole_useDarkMode", val); } // Rendering public static boolean getShowAxis() { return PREFERENCES.getBoolean("whitehole_showAxis", true); } @@ -64,7 +66,4 @@ private Settings() {} public static void setKeyPosition(int val) { PREFERENCES.putInt("whitehole_keyPosition", val); } public static void setKeyRotation(int val) { PREFERENCES.putInt("whitehole_keyRotation", val); } public static void setKeyScale(int val) { PREFERENCES.putInt("whitehole_keyScale", val); } - - @Deprecated - public static boolean legacy; } diff --git a/src/whitehole/SettingsForm.form b/src/whitehole/SettingsForm.form index 01f422a..59956e4 100644 --- a/src/whitehole/SettingsForm.form +++ b/src/whitehole/SettingsForm.form @@ -81,6 +81,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/whitehole/SettingsForm.java b/src/whitehole/SettingsForm.java index 6439295..2edd7d8 100644 --- a/src/whitehole/SettingsForm.java +++ b/src/whitehole/SettingsForm.java @@ -22,10 +22,11 @@ import java.awt.event.KeyEvent; import javax.swing.JButton; import javax.swing.JFrame; +import javax.swing.SwingUtilities; public class SettingsForm extends javax.swing.JDialog { - public SettingsForm() { - super((JFrame)null, true); + public SettingsForm(JFrame parent) { + super(parent, true); initComponents(); @@ -46,6 +47,7 @@ private void initComponents() { pnlSettings = new javax.swing.JPanel(); lblAppearance = new javax.swing.JLabel(); lblControls = new javax.swing.JLabel(); + chkUseDarkMode = new javax.swing.JCheckBox(); chkDisplaySimpleNameDB = new javax.swing.JCheckBox(); chkUseShaders = new javax.swing.JCheckBox(); chkDebugFakeColor = new javax.swing.JCheckBox(); @@ -88,6 +90,19 @@ public void windowClosing(java.awt.event.WindowEvent evt) { gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2); pnlSettings.add(lblControls, gridBagConstraints); + chkUseDarkMode.setSelected(Settings.getUseDarkMode()); + chkUseDarkMode.setText("Use Dark Mode"); + chkUseDarkMode.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + chkUseDarkModeItemStateChanged(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2); + pnlSettings.add(chkUseDarkMode, gridBagConstraints); + chkDisplaySimpleNameDB.setSelected(Settings.getDisplaySimpleNameDB()); chkDisplaySimpleNameDB.setText("Display object database names"); chkDisplaySimpleNameDB.addItemListener(new java.awt.event.ItemListener() { @@ -260,6 +275,14 @@ private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:even Settings.setKeyRotation(((KeybindButton)btnRotation).keybind); Settings.setKeyScale(((KeybindButton)btnScale).keybind); }//GEN-LAST:event_formWindowClosing + + private void chkUseDarkModeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkUseDarkModeItemStateChanged + Settings.setUseDarkMode(evt.getStateChange() == ItemEvent.SELECTED); + + Whitehole.updateLAF(); + SwingUtilities.updateComponentTreeUI(this); + pack(); + }//GEN-LAST:event_chkUseDarkModeItemStateChanged private static class KeybindButton extends JButton { boolean binding = false; @@ -310,6 +333,7 @@ public void setKeyBind(int key) { private javax.swing.JCheckBox chkDebugFakeColor; private javax.swing.JCheckBox chkDebugFastDrag; private javax.swing.JCheckBox chkDisplaySimpleNameDB; + private javax.swing.JCheckBox chkUseDarkMode; private javax.swing.JCheckBox chkUseReverseRot; private javax.swing.JCheckBox chkUseShaders; private javax.swing.JCheckBox chkUseWASD; diff --git a/src/whitehole/Whitehole.java b/src/whitehole/Whitehole.java index 776ba82..9f66daf 100644 --- a/src/whitehole/Whitehole.java +++ b/src/whitehole/Whitehole.java @@ -17,6 +17,7 @@ package whitehole; import com.formdev.flatlaf.FlatDarkLaf; +import com.formdev.flatlaf.FlatLightLaf; import whitehole.db.GalaxyNames; import whitehole.smg.GameArchive; import java.awt.Image; @@ -35,11 +36,18 @@ public class Whitehole { public static final String WEB_URL = "https://discord.gg/k7ZKzSDsVq"; public static final Image ICON = Toolkit.getDefaultToolkit().createImage(Whitehole.class.getResource("/res/icon.png")); + private static FlatDarkLaf DARK_THEME; + private static FlatLightLaf LIGHT_THEME; + public static void main(String[] args) throws IOException { - // Set look and feel if applicable + // Setup look and feel and set if applicable + FlatDarkLaf.setup(); + FlatLightLaf.setup(); + DARK_THEME = new FlatDarkLaf(); + LIGHT_THEME = new FlatLightLaf(); + try { - FlatDarkLaf.setup(); - UIManager.setLookAndFeel(new FlatDarkLaf()); + UIManager.setLookAndFeel(Settings.getUseDarkMode() ? DARK_THEME : LIGHT_THEME); } catch (Exception ex) { System.err.println(ex); @@ -55,6 +63,7 @@ public static void main(String[] args) throws IOException { ); } + // Initialize data FieldHashes.init(); GalaxyNames.init(); ObjectDB.init(); @@ -63,6 +72,30 @@ public static void main(String[] args) throws IOException { new MainFrame().setVisible(true); } + public static void updateLAF() { + LookAndFeel next = null; + + if (Settings.getUseDarkMode()) { + if (UIManager.getLookAndFeel() != DARK_THEME) { + next = DARK_THEME; + } + } + else { + if (UIManager.getLookAndFeel() != LIGHT_THEME) { + next = LIGHT_THEME; + } + } + + if (next != null) { + try { + UIManager.setLookAndFeel(next); + } + catch(Exception ex) { + System.err.println(ex); + } + } + } + // ------------------------------------------------------------------------------------------------------------------------- // Game Util diff --git a/src/whitehole/editor/GalaxyEditorForm.java b/src/whitehole/editor/GalaxyEditorForm.java index 3e88fd0..8c50fd6 100644 --- a/src/whitehole/editor/GalaxyEditorForm.java +++ b/src/whitehole/editor/GalaxyEditorForm.java @@ -244,11 +244,8 @@ public GalaxyEditorForm(GalaxyEditorForm gal_parent, StageArchive zone) { scrLayers.setViewportView(listLayerCheckboxes); zoneModeLayerBitmask = 0; - JCheckBox[] cblayers = new JCheckBox[curZoneArc.objects.keySet().size()]; + JCheckBox[] cblayers = new JCheckBox[curZoneArc.objects.keySet().size() - 1]; int i = 0; - cblayers[i] = new JCheckBox("Common"); - cblayers[i].setSelected(true); - i++; for(int l = 0; l < 16; l++) { String ls = String.format("Layer%1$c", (char) ('A' + l)); if(curZoneArc.objects.containsKey(ls.toLowerCase())) { @@ -1348,7 +1345,7 @@ private void setStatusText() { */ private void layerSelectChange(int index, boolean status) { JCheckBox cbx =(JCheckBox)listLayerCheckboxes.getModel().getElementAt(index); - int layer = cbx.getText().equals("Common") ? 1 :(2 <<(cbx.getText().charAt(5) - 'A')); + int layer = (1 <<(cbx.getText().charAt(5) - 'A')); if(status) zoneModeLayerBitmask |= layer; @@ -2358,6 +2355,8 @@ private void addObject(Object point) { String objname = addingObject.substring(addingObject.indexOf('|') + 1); addingObjectOnLayer = addingObjectOnLayer.toLowerCase(); + TreeNode newNode; + // Add new path? if(objtype.equals("path")) { int newPathLinkID = 0; @@ -2373,29 +2372,22 @@ private void addObject(Object point) { globalPathList.put(thepath.uniqueID, thepath); curZoneArc.paths.add(thepath); - //thepath.createStorage(); - PathPointObj thepoint = new PathPointObj(thepath, position); thepoint.uniqueID = maxUniqueID; - maxUniqueID++; + maxUniqueID += 3; + globalObjList.put(thepoint.uniqueID, thepoint); globalPathPointList.put(thepoint.uniqueID, thepoint); thepath.getPoints().add(thepoint); - DefaultTreeModel objlist =(DefaultTreeModel) treeObjects.getModel(); - ObjListTreeNode listnode =(ObjListTreeNode)((DefaultMutableTreeNode) objlist.getRoot()).getChildAt(StageArchive.game == 2 ? 10 : 11); - ObjListTreeNode newnode =(ObjListTreeNode) listnode.addObject(thepath); - objlist.nodesWereInserted(listnode, new int[] { listnode.getIndex(newnode) }); + ObjListTreeNode newnode = (ObjListTreeNode)objListPathRootNode.addObject(thepath); treeNodeList.put(thepath.uniqueID, newnode); - TreeNode newpointnode = newnode.addObject(thepoint); - objlist.nodesWereInserted(newnode, new int[] { newnode.getIndex(newpointnode) }); - treeNodeList.put(thepoint.uniqueID, newpointnode); + newNode = newnode.addObject(thepoint); + treeNodeList.put(thepoint.uniqueID, newNode); rerenderTasks.add("path:" + thepath.uniqueID); rerenderTasks.add("zone:" + curZone); - glCanvas.repaint(); - unsavedChanges = true; } // Add new path point? else if (objtype.equals("pathpoint")) { @@ -2417,18 +2409,14 @@ else if (objtype.equals("pathpoint")) { globalPathPointList.put(thepoint.uniqueID, thepoint); thepath.getPoints().add(thepoint); - DefaultTreeModel objlist =(DefaultTreeModel) treeObjects.getModel(); - ObjListTreeNode listnode =(ObjListTreeNode)((DefaultMutableTreeNode) objlist.getRoot()).getChildAt(StageArchive.game == 2 ? 10 : 11); + ObjListTreeNode listnode = objListPathRootNode; listnode =(ObjListTreeNode) listnode.children.get(thepath.uniqueID); - TreeNode newnode = listnode.addObject(thepoint); - objlist.nodesWereInserted(listnode, new int[] { listnode.getIndex(newnode) }); - treeNodeList.put(thepoint.uniqueID, newnode); - + newNode = listnode.addObject(thepoint); + treeNodeList.put(thepoint.uniqueID, newNode); + rerenderTasks.add("path:" + thepath.uniqueID); rerenderTasks.add("zone:" + thepath.stage.stageName); - glCanvas.repaint(); - unsavedChanges = true; } else { newobj = null; @@ -2465,15 +2453,22 @@ else if (objtype.equals("pathpoint")) { globalObjList.put(uniqueID, newobj); curZoneArc.objects.get(addingObjectOnLayer).add(newobj); - ObjTreeNode newnode = objListTreeNodes.get(objtype).addObject(newobj); - treeNodeList.put(uniqueID, newnode); + newNode = objListTreeNodes.get(objtype).addObject(newobj); + treeNodeList.put(uniqueID, newNode); // Update rendering rerenderTasks.add(String.format("addobj:%1$d", uniqueID)); rerenderTasks.add("zone:" + curZone); - glCanvas.repaint(); - unsavedChanges = true; } + + // Update tree node model and scroll to new node + objListModel.reload(); + TreePath path = new TreePath(objListModel.getPathToRoot(newNode)); + treeObjects.setSelectionPath(path); + treeObjects.scrollPathToVisible(path); + + glCanvas.repaint(); + unsavedChanges = true; } private void deleteObject(int uniqueID) { @@ -3323,8 +3318,8 @@ private void renderZone(GL2 gl, Bcsv.Entry scenario, String zone, int layermask, gl.glCallList(objDisplayLists.get(zone + "/common")[mode]); - for(int l = 0; l < 16; l++) { - if((layermask &(1 << l)) != 0) + for (int l = 0; l < 16; l++) { + if((layermask & (1 << l)) != 0) gl.glCallList(objDisplayLists.get(zone + "/layer" + alphabet.charAt(l))[mode]); } diff --git a/src/whitehole/editor/ObjectSelectForm.java b/src/whitehole/editor/ObjectSelectForm.java index f1c221e..4bd79b9 100644 --- a/src/whitehole/editor/ObjectSelectForm.java +++ b/src/whitehole/editor/ObjectSelectForm.java @@ -194,8 +194,9 @@ public void showNewObject(String objectType, List layerNames) { populate(); + cmoLayer.removeAllItems(); + for (String layer : layerNames) { - System.out.println(layer); cmoLayer.addItem(layer); } diff --git a/src/whitehole/io/ExternalFilesystem.java b/src/whitehole/io/ExternalFilesystem.java index e484fd4..6c51d33 100644 --- a/src/whitehole/io/ExternalFilesystem.java +++ b/src/whitehole/io/ExternalFilesystem.java @@ -52,7 +52,7 @@ public List getDirectories(String directory) { ret.add(file.getName()); } } catch(Exception ex) { - MainFrame.lbStatusBar.setText("Failed to open game directory."); + System.err.println(ex); } return ret; diff --git a/src/whitehole/rendering/BmdRenderer.java b/src/whitehole/rendering/BmdRenderer.java index 1f8e60a..39c6b69 100644 --- a/src/whitehole/rendering/BmdRenderer.java +++ b/src/whitehole/rendering/BmdRenderer.java @@ -581,8 +581,7 @@ protected final void ctor_uploadData(RenderInfo info) throws GLException { } for(int i = 0; i < model.materials.length; i++) { try { - if(!Settings.legacy) - generateShaders(gl, i); + generateShaders(gl, i); } catch(GLException ex) { // really ugly hack @@ -731,11 +730,9 @@ public void render(RenderInfo info) throws GLException { if(info.renderMode != RenderMode.PICKING) { if((mat.drawFlag == 4) ^(info.renderMode == RenderMode.TRANSLUCENT)) continue; - if(Settings.legacy) - hasShaders = false; if(hasShaders) { // shader: handles multitexturing, color combination, alpha test - if(gl.isFunctionAvailable("glUseProgram") && !Settings.legacy) + if(gl.isFunctionAvailable("glUseProgram")) gl.glUseProgram(shaders[node.materialID].program); // do multitexturing