diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/EditableMatDefFile.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/EditableMatDefFile.java index f3325bfc8..5c196c8cf 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/EditableMatDefFile.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/EditableMatDefFile.java @@ -5,7 +5,6 @@ package com.jme3.gde.materialdefinition; import com.jme3.asset.AssetKey; -import com.jme3.asset.MaterialKey; import com.jme3.gde.core.assets.ProjectAssetManager; import com.jme3.gde.core.scene.SceneApplication; import com.jme3.gde.materialdefinition.fileStructure.MatDefBlock; @@ -14,12 +13,14 @@ import com.jme3.gde.materialdefinition.fileStructure.TechniqueBlock; import com.jme3.gde.materialdefinition.fileStructure.UberStatement; import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; import com.jme3.gde.materialdefinition.fileStructure.leaves.LeafStatement; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock; import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock; import com.jme3.gde.materialdefinition.navigator.node.MatDefNode; import com.jme3.material.MatParam; import com.jme3.material.Material; import com.jme3.material.MaterialDef; import com.jme3.material.plugins.J3MLoader; +import com.jme3.material.plugins.MatParseException; import com.jme3.shader.Glsl100ShaderGenerator; import com.jme3.shader.Glsl150ShaderGenerator; import com.jme3.shader.Shader; @@ -30,7 +31,6 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.util.ArrayList; -import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.logging.Level; @@ -68,29 +68,52 @@ public class EditableMatDefFile { private final static String GLSL100 = "GLSL100"; private final static String GLSL150 = "GLSL150"; private Lookup lookup; + private boolean loaded = false; + private boolean dirty = false; public EditableMatDefFile(Lookup lookup) { obj = lookup.lookup(MatDefDataObject.class); + load(lookup); + } + + public final void load(Lookup lookup) { this.matDefFile = obj.getPrimaryFile(); this.assetManager = lookup.lookup(ProjectAssetManager.class); this.glsl100 = new Glsl100ShaderGenerator(assetManager); this.glsl150 = new Glsl150ShaderGenerator(assetManager); this.lookup = lookup; - materialDef = null; - matDefStructure = null; + if (matDefStructure != null) { + obj.getLookupContents().remove(matDefStructure); + matDefStructure = null; + } + if (materialDef != null) { + obj.getLookupContents().remove(materialDef); + materialDef = null; + } FileLock lock = null; - try { lock = matDefFile.lock(); List sta = BlockLanguageParser.parse(obj.getPrimaryFile().getInputStream()); matDefStructure = new MatDefBlock(sta.get(0)); - // System.err.println(block.toString()); + AssetKey matDefKey = new AssetKey(assetManager.getRelativeAssetPath(assetManager.getRelativeAssetPath(matDefFile.getPath()))); + assetManager.deleteFromCache(matDefKey); materialDef = (MaterialDef) assetManager.loadAsset(assetManager.getRelativeAssetPath(matDefFile.getPath())); lock.releaseLock(); } catch (Exception ex) { - Exceptions.printStackTrace(ex); + Throwable t = ex.getCause(); + boolean matParseError = false; + while (t != null) { + if (t instanceof MatParseException) { + Logger.getLogger(EditableMatDefFile.class.getName()).log(Level.SEVERE, t.getMessage()); + matParseError = true; + } + t = t.getCause(); + } + if (!matParseError) { + Exceptions.printStackTrace(ex); + } } finally { if (lock != null) { lock.releaseLock(); @@ -99,10 +122,11 @@ public class EditableMatDefFile { if (materialDef != null) { currentTechnique = matDefStructure.getTechniques().get(0); registerListener(matDefStructure); + obj.getLookupContents().add(matDefStructure); updateLookupWithMaterialData(obj); + loaded = true; } - } private void registerListener(Statement sta) { @@ -130,7 +154,7 @@ public class EditableMatDefFile { public String getShaderCode(String version, Shader.ShaderType type) { try { material.selectTechnique("Default", SceneApplication.getApplication().getRenderManager()); - Shader s = null; + Shader s; if (version.equals(GLSL100)) { s = glsl100.generateShader(material.getActiveTechnique()); } else { @@ -186,6 +210,22 @@ public class EditableMatDefFile { } } + public boolean isLoaded() { + return loaded; + } + + public boolean isDirty() { + return dirty; + } + + public void setDirty(boolean dirty) { + this.dirty = dirty; + } + + public void setLoaded(boolean loaded) { + this.loaded = loaded; + } + private class MatStructChangeListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { @@ -214,6 +254,32 @@ public class EditableMatDefFile { } } } + if (evt.getPropertyName().equals(MatDefBlock.REMOVE_MAT_PARAM)) { + MatParamBlock oldValue = (MatParamBlock) evt.getOldValue(); + + for (ShaderNodeBlock shaderNodeBlock : currentTechnique.getShaderNodes()) { + + if (shaderNodeBlock.getCondition() != null && shaderNodeBlock.getCondition().contains(oldValue.getName())) { + shaderNodeBlock.setCondition(shaderNodeBlock.getCondition().replaceAll(oldValue.getName(), "").trim()); + } + List lin = shaderNodeBlock.getInputs(); + if (lin != null) { + for (InputMappingBlock inputMappingBlock : shaderNodeBlock.getInputs()) { + if (inputMappingBlock.getCondition() != null && inputMappingBlock.getCondition().contains(oldValue.getName())) { + inputMappingBlock.setCondition(inputMappingBlock.getCondition().replaceAll(oldValue.getName(), "").trim()); + } + } + } + List l = shaderNodeBlock.getOutputs(); + if (l != null) { + for (OutputMappingBlock outputMappingBlock : l) { + if (outputMappingBlock.getCondition() != null && outputMappingBlock.getCondition().contains(oldValue.getName())) { + outputMappingBlock.setCondition(outputMappingBlock.getCondition().replaceAll(oldValue.getName(), "").trim()); + } + } + } + } + } if (evt.getPropertyName().equals(MatDefBlock.ADD_MAT_PARAM) || evt.getPropertyName().equals(TechniqueBlock.ADD_SHADER_NODE) || evt.getPropertyName().equals(ShaderNodeBlock.ADD_MAPPING)) { @@ -257,8 +323,5 @@ public class EditableMatDefFile { Logger.getLogger(EditableMatDefFile.class.getName()).log(Level.SEVERE, ex.getMessage()); } updateLookupWithMaterialData(obj); - AssetKey matDefKey = new AssetKey(assetManager.getRelativeAssetPath(assetManager.getRelativeAssetPath(matDefFile.getPath()))); - assetManager.deleteFromCache(matDefKey); - } } diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefDataObject.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefDataObject.java index 0e4fae611..d61c0b662 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefDataObject.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefDataObject.java @@ -33,6 +33,8 @@ package com.jme3.gde.materialdefinition; import com.jme3.gde.core.assets.ProjectAssetManager; import com.jme3.gde.materialdefinition.navigator.MatDefNavigatorPanel; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; import java.io.IOException; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectManager; @@ -41,9 +43,7 @@ import org.netbeans.core.spi.multiview.text.MultiViewEditorElement; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.awt.ActionReferences; -import org.openide.cookies.SaveCookie; import org.openide.filesystems.FileChangeAdapter; -import org.openide.filesystems.FileChangeListener; import org.openide.filesystems.FileEvent; import org.openide.filesystems.FileObject; import org.openide.filesystems.MIMEResolver; @@ -140,14 +140,16 @@ public class MatDefDataObject extends MultiDataObject { findAssetManager(); final MatDefMetaData metaData = new MatDefMetaData(this); lookupContents.add(metaData); - pf.addFileChangeListener(new FileChangeAdapter(){ - + pf.addFileChangeListener(new FileChangeAdapter() { @Override public void fileChanged(FileEvent fe) { super.fileChanged(fe); metaData.save(); + if (file.isDirty()) { + file.setLoaded(false); + file.setDirty(false); + } } - }); } @@ -202,6 +204,33 @@ public class MatDefDataObject extends MultiDataObject { nav.updateData(obj); } MultiViewEditorElement ed = new MultiViewEditorElement(lkp) { + KeyListener listener = new KeyListener() { + public void keyTyped(KeyEvent e) { + } + + public void keyPressed(KeyEvent e) { + EditableMatDefFile f = obj.getEditableFile(); + if (f != null) { + f.setDirty(true); + } + } + + public void keyReleased(KeyEvent e) { + } + }; + + @Override + public void componentActivated() { + super.componentActivated(); + getEditorPane().addKeyListener(listener); + } + + @Override + public void componentDeactivated() { + super.componentDeactivated(); + getEditorPane().removeKeyListener(listener); + } + @Override public void componentClosed() { super.componentClosed(); @@ -247,11 +276,7 @@ public class MatDefDataObject extends MultiDataObject { metaData.duplicate(df, name); return super.handleCopyRename(df, name, ext); } - - - - public EditableMatDefFile getEditableFile() { if (file == null) { file = new EditableMatDefFile(getLookup()); diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefMetaData.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefMetaData.java index 5193186b2..e3879af01 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefMetaData.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefMetaData.java @@ -126,7 +126,7 @@ public class MatDefMetaData { if (prop == null) { return defaultProps.getProperty(key); } - return prop; + return prop; } }); } @@ -139,7 +139,7 @@ public class MatDefMetaData { return ret; } }); - // writeProperties(); + // writeProperties(); notifyListeners(key, ret, value); return ret; } @@ -308,10 +308,12 @@ public class MatDefMetaData { } - public void save(){ - writeProperties(); + public void save() { + if (!props.isEmpty()) { + writeProperties(); + } } - + private void writeProperties() { //writeAccess because we write lastMod date, not because we write to the file //the mutex protects the properties object, not the file diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java index c7a2954b5..4befb01c6 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java @@ -380,6 +380,14 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene return item; } + + public void clear(){ + removeAll(); + outBuses.clear(); + connections.clear(); + nodes.clear(); + } + private void createPopupMenu() { contextMenu.setFont(new Font("Tahoma", 1, 10)); // NOI18N contextMenu.setOpaque(true); diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.java index bdef62cb2..e684ed388 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.java @@ -50,14 +50,19 @@ import com.jme3.shader.Shader; import com.jme3.shader.ShaderNodeDefinition; import com.jme3.shader.ShaderNodeVariable; import com.jme3.shader.ShaderUtils; +import java.awt.Color; import java.awt.Dimension; import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.beans.PropertyVetoException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.swing.Action; +import javax.swing.JButton; import javax.swing.JComponent; +import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JToolBar; import org.netbeans.core.spi.multiview.CloseOperationState; @@ -91,12 +96,17 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme Selectable prevNode; MatDefMetaData metaData; - public MatDefEditorlElement(Lookup lkp) { + public MatDefEditorlElement(final Lookup lkp) { + initComponents(); obj = lkp.lookup(MatDefDataObject.class); metaData = lkp.lookup(MatDefMetaData.class); assert obj != null; - EditableMatDefFile file = obj.getEditableFile(); - initComponents(); + final EditableMatDefFile file = obj.getEditableFile(); + reload(file, lkp); + } + + private void initDiagram(Lookup lkp) throws NumberFormatException { + diagram1.clear(); diagram1.setParent(this); Material mat = lkp.lookup(Material.class); @@ -223,9 +233,6 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme } }); } - - - } @Override @@ -353,6 +360,10 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme @Override public void componentActivated() { + if (!obj.getEditableFile().isLoaded()) { + obj.getEditableFile().load(obj.getLookup()); + reload(obj.getEditableFile(), obj.getLookup()); + } } @Override @@ -542,7 +553,6 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme private TechniqueBlock getTechnique(MatDefBlock matDef) { TechniqueBlock technique = matDef.getTechniques().get(0); - return technique; } @@ -563,4 +573,32 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme metaData.setProperty(diagram1.getCurrentTechniqueName() + "/" + key, x + "," + y); } + + private void reload(final EditableMatDefFile file, final Lookup lkp) throws NumberFormatException { + if (file.isLoaded()) { + initDiagram(lkp); + MatDefNavigatorPanel nav = obj.getLookup().lookup(MatDefNavigatorPanel.class); + if (nav != null) { + nav.updateData(obj); + } + } else { + diagram1.clear(); + JLabel error = new JLabel("Cannot load material definition."); + error.setForeground(Color.RED); + error.setBounds(0, 0, 200, 20); + diagram1.add(error); + JButton btn = new JButton("retry"); + btn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + file.load(lkp); + if (file.isLoaded()) { + initDiagram(lkp); + } + } + }); + btn.setBounds(0, 25, 150, 20); + diagram1.add(btn); + + } + } } diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MatDefBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MatDefBlock.java index 203181951..1aacd3cc9 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MatDefBlock.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MatDefBlock.java @@ -80,7 +80,7 @@ public class MatDefBlock extends UberStatement { techniqueBlock.cleanMappings(vblock, "MatParam", matParam.getName()); techniqueBlock.cleanMappings(fblock, "MatParam", matParam.getName()); } - fire(REMOVE_MAT_PARAM, null, matParam); + fire(REMOVE_MAT_PARAM, matParam, null); } public List getTechniques() { diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.java index 035513798..1c0622eec 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.java @@ -166,17 +166,4 @@ public class MatDefNavigatorPanel extends JPanel implements NavigatorPanel, Expl private javax.swing.JScrollPane jScrollPane1; // End of variables declaration//GEN-END:variables - /** - * Gets default instance. Do not use directly: reserved for *.settings files - * only, i.e. deserialization routines; otherwise you could get a - * non-deserialized instance. To obtain the singleton instance, use - * {@link #findInstance}. - */ - public static synchronized MatDefNavigatorPanel getDefault() { - if (instance == null) { - instance = new MatDefNavigatorPanel(); - } - return instance; - } - private static MatDefNavigatorPanel instance; }