From 576e18b376ff5d937bd63c3f148182d30cb39cb8 Mon Sep 17 00:00:00 2001 From: Nehon Date: Thu, 29 Jan 2015 23:50:20 +0100 Subject: [PATCH] You can now directly edit shader node's code inside the shader node editor and benefit from a live reload feature of the shader. --- .../dialog/AddNodeDialog.java | 2 +- .../editor/Bundle.properties | 5 + .../materialdefinition/editor/Diagram.java | 6 +- .../editor/DraggablePanel.java | 4 +- .../editor/MatDefEditorlElement.form | 73 ++++-- .../editor/MatDefEditorlElement.java | 76 +++++- .../materialdefinition/editor/NodePanel.java | 18 ++ .../editor/OutBusPanel.java | 2 +- .../materialdefinition/editor/Selectable.java | 2 +- .../editor/ShaderEditPanel.form | 162 ++++++++++++ .../editor/ShaderEditPanel.java | 244 ++++++++++++++++++ .../gde/materialdefinition/icons/Icons.java | 10 + .../gde/materialdefinition/icons/error.png | Bin 0 -> 48461 bytes .../utils/DocFormatter.java | 2 +- .../materials/MaterialPreviewRenderer.java | 12 + 15 files changed, 585 insertions(+), 33 deletions(-) create mode 100644 sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Bundle.properties create mode 100644 sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ShaderEditPanel.form create mode 100644 sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ShaderEditPanel.java create mode 100644 sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/error.png diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddNodeDialog.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddNodeDialog.java index cb9602553..ca185eb4a 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddNodeDialog.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddNodeDialog.java @@ -28,7 +28,7 @@ import javax.swing.tree.TreeSelectionModel; /** * - * @author m327836 + * @author Nehon */ public class AddNodeDialog extends javax.swing.JDialog { diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Bundle.properties b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Bundle.properties new file mode 100644 index 000000000..64e6fb8b9 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Bundle.properties @@ -0,0 +1,5 @@ +ShaderEditPanel.closeButton.text= +ShaderEditPanel.shaderEditorPane.text= +ShaderEditPanel.closeButton.toolTipText=Close this panel +ShaderEditPanel.jToggleButton1.text=jToggleButton1 +ShaderEditPanel.headerText.text=jLabel1 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 4befb01c6..fcd851ed6 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 @@ -134,7 +134,11 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene } repaint(); } - + + protected void showEdit(NodePanel node) { + parent.showShaderEditor(node.getName(),node.getType(),node.filePaths); + } + public void notifyMappingCreation(Connection conn) { parent.makeMapping(conn); } diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java index 73568963b..5ba949c9a 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java @@ -11,7 +11,7 @@ import javax.swing.JPanel; /** * - * @author m327836 + * @author Nehon */ public class DraggablePanel extends JPanel implements MouseListener, MouseMotionListener { @@ -44,7 +44,7 @@ public class DraggablePanel extends JPanel implements MouseListener, MouseMotion svdey = e.getYOnScreen(); e.consume(); } - + @Override public void mouseReleased(MouseEvent e) { } diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.form index 9c82d4931..2cca23230 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.form +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.form @@ -1,6 +1,6 @@ -
+ @@ -16,39 +16,72 @@ - + - + - + + + + + - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + 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 f6f6df0f1..fe2f9b605 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 @@ -56,6 +56,7 @@ import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyVetoException; +import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -69,6 +70,8 @@ import org.netbeans.core.spi.multiview.CloseOperationState; import org.netbeans.core.spi.multiview.MultiViewElement; import org.netbeans.core.spi.multiview.MultiViewElementCallback; import org.openide.awt.UndoRedo; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.Exceptions; @@ -103,13 +106,16 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme metaData = lkp.lookup(MatDefMetaData.class); assert obj != null; final EditableMatDefFile file = obj.getEditableFile(); - reload(file, lkp); + shaderEditPanel1.setVisible(false); + shaderEditPanel1.setParent(this); + reload(file, lkp); } private void initDiagram(Lookup lkp) throws NumberFormatException { + diagram1.clear(); diagram1.setParent(this); - + Material mat = lkp.lookup(Material.class); ProjectAssetManager manager = obj.getLookup().lookup(ProjectAssetManager.class); @@ -260,6 +266,45 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme Exceptions.printStackTrace(ex); } } + + public void refresh() { + + Lookup.Result resMat = obj.getLookup().lookupResult(Material.class); + Collection col = (Collection) resMat.allInstances(); + if (!col.isEmpty()) { + Material material = col.iterator().next(); + diagram1.refreshPreviews(material); + } + + } + + public void setModified(){ + obj.setModified(true); + } + + public ProjectAssetManager getAssetManager(){ + return obj.getLookup().lookup(ProjectAssetManager.class); + } + + public void showShaderEditor(String nodeName,NodePanel.NodeType type,ListpathList){ + + List fos = new ArrayList(); + for (String path : pathList) { + FileObject text = FileUtil.toFileObject(new File(getAssetManager().getAbsoluteAssetPath(path))); + fos.add(text); + } + shaderEditPanel1.setFiles(nodeName, type, fos); + shaderEditPanel1.revalidate(); + if(!shaderEditPanel1.isVisible() || jSplitPane.getDividerLocation() == jSplitPane.getMinimumDividerLocation()){ + shaderEditPanel1.setVisible(true); + jSplitPane.setDividerLocation(650); + } + + } + + public ShaderEditPanel getShaderEditor(){ + return shaderEditPanel1; + } private Node findNode(Node root, String key) { if (root instanceof Selectable) { @@ -289,38 +334,53 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme // //GEN-BEGIN:initComponents private void initComponents() { + jSplitPane = new javax.swing.JSplitPane(); + shaderEditPanel1 = new com.jme3.gde.materialdefinition.editor.ShaderEditPanel(); jScrollPane1 = new javax.swing.JScrollPane(); diagram1 = new com.jme3.gde.materialdefinition.editor.Diagram(); + jSplitPane.setDividerLocation(1); + jSplitPane.setDividerSize(6); + + shaderEditPanel1.setMinimumSize(new java.awt.Dimension(0, 0)); + jSplitPane.setLeftComponent(shaderEditPanel1); + + jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 0)); + jScrollPane1.setName(""); // NOI18N + diagram1.setBackground(new java.awt.Color(153, 153, 153)); javax.swing.GroupLayout diagram1Layout = new javax.swing.GroupLayout(diagram1); diagram1.setLayout(diagram1Layout); diagram1Layout.setHorizontalGroup( diagram1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 398, Short.MAX_VALUE) + .addGap(0, 1591, Short.MAX_VALUE) ); diagram1Layout.setVerticalGroup( diagram1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 298, Short.MAX_VALUE) + .addGap(0, 782, Short.MAX_VALUE) ); jScrollPane1.setViewportView(diagram1); + jSplitPane.setRightComponent(jScrollPane1); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1) + .addComponent(jSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 470, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1) + .addComponent(jSplitPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE) ); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables private com.jme3.gde.materialdefinition.editor.Diagram diagram1; private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JSplitPane jSplitPane; + private com.jme3.gde.materialdefinition.editor.ShaderEditPanel shaderEditPanel1; // End of variables declaration//GEN-END:variables @Override @@ -572,6 +632,10 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme metaData.setProperty(diagram1.getCurrentTechniqueName() + "/" + key, x + "," + y); } + + public void reload(){ + reload(obj.getEditableFile(), obj.getLookup()); + } private void reload(final EditableMatDefFile file, final Lookup lkp) throws NumberFormatException { if (file.isLoaded()) { diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java index 58e2a7b2d..49f94fe7d 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java @@ -5,6 +5,7 @@ package com.jme3.gde.materialdefinition.editor; import com.jme3.gde.materialdefinition.fileStructure.ShaderNodeBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.DefinitionBlock; import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock; import com.jme3.gde.materialdefinition.icons.Icons; @@ -51,6 +52,7 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha private Color color; private String name; private String techName; + protected List filePaths= new ArrayList(); // private List listeners = Collections.synchronizedList(new LinkedList()); // @@ -106,6 +108,9 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha this.addPropertyChangeListener(WeakListeners.propertyChange(node, this)); refresh(node); addKeyListener(this); + this.filePaths.addAll(def.getShadersPath()); + String defPath = ((DefinitionBlock)node.getContents().get(0)).getPath(); + this.filePaths.add(defPath); } /** @@ -311,6 +316,19 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha header.addMouseMotionListener(labelMouseMotionListener); header.setHorizontalAlignment(SwingConstants.LEFT); header.setFont(new Font("Tahoma", Font.BOLD, 11)); + header.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + //if(e.getClickCount()==2){ + if (type==NodeType.Fragment || type == NodeType.Vertex) { + diagram.showEdit(NodePanel.this); + } + //} + } + + }); + content = new JPanel(); content.setOpaque(false); GroupLayout contentLayout = new GroupLayout(content); diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java index 2070f0d10..8863b9fd6 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java @@ -25,7 +25,7 @@ import javax.swing.SwingUtilities; /** * - * @author m327836 + * @author Nehon */ public class OutBusPanel extends DraggablePanel implements ComponentListener, Selectable, InOut { diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Selectable.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Selectable.java index 201e30d81..e00746546 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Selectable.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Selectable.java @@ -6,7 +6,7 @@ package com.jme3.gde.materialdefinition.editor; /** * - * @author m327836 + * @author Nehon */ public interface Selectable { diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ShaderEditPanel.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ShaderEditPanel.form new file mode 100644 index 000000000..79d9bbe40 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ShaderEditPanel.form @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ShaderEditPanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ShaderEditPanel.java new file mode 100644 index 000000000..44b511583 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ShaderEditPanel.java @@ -0,0 +1,244 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.editor; + +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.shader.Shader; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.List; +import javax.swing.JPanel; +import javax.swing.JToggleButton; +import javax.swing.text.EditorKit; +import org.openide.filesystems.FileObject; +import org.openide.loaders.DataObject; +import org.openide.loaders.DataObjectNotFoundException; +import org.openide.text.CloneableEditorSupport; +import org.openide.util.Exceptions; + +/** + * + * @author Nehon + */ +public class ShaderEditPanel extends JPanel { + + private DataObject currentDataObject = null; + private MatDefEditorlElement parent = null; + + /** + * Creates new form ShaderEditPanel + */ + public ShaderEditPanel() { + initComponents(); + String mime = "text/x-glsl"; + EditorKit ek = CloneableEditorSupport.getEditorKit(mime); + shaderEditorPane.setEditorKit(ek); + shaderEditorPane.setContentType(mime); + shaderEditorPane.addKeyListener(new KeyListener() { + + public void keyTyped(KeyEvent e) { + currentDataObject.setModified(true); + } + + public void keyPressed(KeyEvent e) { + if ((e.getKeyCode() == KeyEvent.VK_S) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { + saveCurrent(); + } + } + + public void keyReleased(KeyEvent e) { + } + }); + } + + public void setParent(MatDefEditorlElement parent) { + this.parent = parent; + } + + public void setFiles(String title, NodePanel.NodeType type, List fos) { + + headerText.setText(title); + headerText.setIcon(Icons.getIconForShaderType(type)); + boolean firstItem = true; + for (Component component : buttonPanel.getComponents()) { + buttonGroup1.remove((JToggleButton) component); + } + buttonPanel.removeAll(); + buttonPanel.repaint(); + + for (FileObject fo : fos) { + final Tab b = new Tab(); + b.setText(fo.getNameExt()); + buttonGroup1.add(b); + try { + b.dataObject = DataObject.find(fo); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + saveCurrent(); + try { + shaderEditorPane.setText(b.dataObject.getPrimaryFile().asText()); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + currentDataObject = b.dataObject; + } + + }); + if (firstItem) { + shaderEditorPane.setText(fo.asText()); + currentDataObject = b.dataObject; + b.setSelected(true); + firstItem = false; + } + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + + buttonPanel.add(b); + } + + } + + public void saveCurrent() { + if (currentDataObject != null && currentDataObject.isModified()) { + try { + OutputStreamWriter out = new OutputStreamWriter(currentDataObject.getPrimaryFile().getOutputStream()); + out.write(shaderEditorPane.getText(), 0, shaderEditorPane.getText().length()); + out.close(); + currentDataObject.setModified(false); + if(currentDataObject.getPrimaryFile().getExt().equalsIgnoreCase("j3sn")){ + parent.reload(); + } + parent.refresh(); + } catch (DataObjectNotFoundException ex) { + Exceptions.printStackTrace(ex); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + } + + private class Tab extends JToggleButton { + + DataObject dataObject; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + buttonGroup1 = new javax.swing.ButtonGroup(); + jScrollPane1 = new javax.swing.JScrollPane(); + shaderEditorPane = new javax.swing.JEditorPane(); + header = new javax.swing.JPanel(); + headerText = new javax.swing.JLabel(); + closeButton = new javax.swing.JButton(); + buttonPanel = new javax.swing.JPanel(); + jToggleButton1 = new javax.swing.JToggleButton(); + + jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 0)); + + shaderEditorPane.setBorder(null); + shaderEditorPane.setText(org.openide.util.NbBundle.getMessage(ShaderEditPanel.class, "ShaderEditPanel.shaderEditorPane.text")); // NOI18N + jScrollPane1.setViewportView(shaderEditorPane); + + header.setBackground(java.awt.SystemColor.activeCaption); + header.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + + headerText.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N + headerText.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + headerText.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materialdefinition/icons/fragment.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(headerText, org.openide.util.NbBundle.getMessage(ShaderEditPanel.class, "ShaderEditPanel.headerText.text")); // NOI18N + + closeButton.setBackground(java.awt.SystemColor.activeCaption); + closeButton.setFont(new java.awt.Font("Tahoma", 1, 8)); // NOI18N + closeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materialdefinition/icons/out.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(ShaderEditPanel.class, "ShaderEditPanel.closeButton.text")); // NOI18N + closeButton.setToolTipText(org.openide.util.NbBundle.getMessage(ShaderEditPanel.class, "ShaderEditPanel.closeButton.toolTipText")); // NOI18N + closeButton.setMargin(new java.awt.Insets(0, 0, 0, 0)); + closeButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + closeButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout headerLayout = new javax.swing.GroupLayout(header); + header.setLayout(headerLayout); + headerLayout.setHorizontalGroup( + headerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(headerLayout.createSequentialGroup() + .addComponent(headerText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(closeButton)) + ); + headerLayout.setVerticalGroup( + headerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(headerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(headerText, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + buttonPanel.setAlignmentX(0.0F); + buttonPanel.setAlignmentY(0.0F); + buttonPanel.setPreferredSize(new java.awt.Dimension(73, 29)); + buttonPanel.setLayout(new javax.swing.BoxLayout(buttonPanel, javax.swing.BoxLayout.LINE_AXIS)); + + org.openide.awt.Mnemonics.setLocalizedText(jToggleButton1, org.openide.util.NbBundle.getMessage(ShaderEditPanel.class, "ShaderEditPanel.jToggleButton1.text")); // NOI18N + buttonPanel.add(jToggleButton1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(header, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 645, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(buttonPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(header, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 492, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed + setVisible(false); + + saveCurrent(); + + + }//GEN-LAST:event_closeButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.ButtonGroup buttonGroup1; + private javax.swing.JPanel buttonPanel; + private javax.swing.JButton closeButton; + private javax.swing.JPanel header; + private javax.swing.JLabel headerText; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JToggleButton jToggleButton1; + private javax.swing.JEditorPane shaderEditorPane; + // End of variables declaration//GEN-END:variables +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Icons.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Icons.java index 7e746346e..e06cb7546 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Icons.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Icons.java @@ -4,6 +4,7 @@ */ package com.jme3.gde.materialdefinition.icons; +import com.jme3.gde.materialdefinition.editor.NodePanel; import javax.swing.ImageIcon; /** @@ -27,4 +28,13 @@ public class Icons { public final static ImageIcon tech = new ImageIcon(Icons.class.getResource("tech.png")); public final static ImageIcon in = new ImageIcon(Icons.class.getResource("in.png")); public final static ImageIcon out = new ImageIcon(Icons.class.getResource("out.png")); + public final static ImageIcon error = new ImageIcon(Icons.class.getResource("error.png")); + + public static ImageIcon getIconForShaderType(NodePanel.NodeType type) { + if (type == NodePanel.NodeType.Fragment) { + return frag; + } else { + return vert; + } + } } diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/error.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/error.png new file mode 100644 index 0000000000000000000000000000000000000000..3e9047cea50cac44b3c4bcf3cc27a8a16ea66180 GIT binary patch literal 48461 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 YyJ;4TL<-z$1CTDm2PV3;+Kw;(2dp5n#{d8T literal 0 HcmV?d00001 diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/utils/DocFormatter.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/utils/DocFormatter.java index aaa66fde3..f28778cb0 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/utils/DocFormatter.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/utils/DocFormatter.java @@ -17,7 +17,7 @@ import javax.swing.text.StyledDocument; /** * - * @author m327836 + * @author Nehon */ public class DocFormatter { diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialPreviewRenderer.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialPreviewRenderer.java index 96d005577..e49409e69 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialPreviewRenderer.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialPreviewRenderer.java @@ -11,6 +11,7 @@ import com.jme3.gde.core.scene.PreviewRequest; import com.jme3.gde.core.scene.SceneApplication; import com.jme3.gde.core.scene.SceneListener; import com.jme3.gde.core.scene.SceneRequest; +import com.jme3.gde.materialdefinition.icons.Icons; import com.jme3.material.MatParam; import com.jme3.material.Material; import com.jme3.math.FastMath; @@ -111,6 +112,11 @@ public class MaterialPreviewRenderer implements SceneListener { SceneApplication.getApplication().createPreview(request); } } catch (Exception e) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + label.setIcon(Icons.error); + } + }); Logger.getLogger(MaterialPreviewRenderer.class.getName()).log(Level.SEVERE, "Error rendering material{0}", e.getMessage()); } } @@ -148,6 +154,12 @@ public class MaterialPreviewRenderer implements SceneListener { //the following code will output the error //System.err.println(e.getMessage()); Logger.getLogger(MaterialDebugAppState.class.getName()).log(Level.SEVERE, e.getMessage()); + + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + label.setIcon(Icons.error); + } + }); return null; }