SDK mat def editor :

- better handling of errors in the material definition
- the navigator now properly refreshs
- the editor is reloaded when a change occur in the text file


git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10456 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 12 years ago
parent 503adbfd85
commit 08edd2715c
  1. 87
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/EditableMatDefFile.java
  2. 43
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefDataObject.java
  3. 12
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefMetaData.java
  4. 8
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java
  5. 52
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.java
  6. 2
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MatDefBlock.java
  7. 13
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.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<Statement> 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<InputMappingBlock> 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<OutputMappingBlock> 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);
}
}

@ -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());

@ -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

@ -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);

@ -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);
}
}
}

@ -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<TechniqueBlock> getTechniques() {

@ -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;
}

Loading…
Cancel
Save