/*
* This file is part of MoleculeViewer.
*
* MoleculeViewer is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MoleculeViewer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with MoleculeViewer. If not, see <http://www.gnu.org/licenses/>.
*/
package astex;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import jclass.bwt.*;
class ObjectPropertyDialog extends Dialog
implements
WindowListener, JCActionListener, JCSpinBoxListener {
/** The only instance of an ObjectPropertyDialog. */
private static ObjectPropertyDialog opd = null;
/** The object that we are currently operating on. */
private Tmesh object = null;
/** The MoleculeRenderer object. */
private MoleculeRenderer moleculeRenderer = null;
/** Is the object active yet. */
private boolean active = false;
/** Create the instance of the opd. */
public synchronized static ObjectPropertyDialog
getInstance(Frame f, String label,
MoleculeRenderer mr){
if(opd == null){
opd = new ObjectPropertyDialog(f, label, mr);
}
return opd;
}
/** Set the tmesh object that is being edited. */
public void setTmesh(Tmesh tm){
object = tm;
setMinMax();
}
/**
* Create a dialog that lets us edit the texture based
* properties of a tmesh object.
*/
private ObjectPropertyDialog(Frame f, String label,
MoleculeRenderer mr){
super(f, label, false);
moleculeRenderer = mr;
addWindowListener(this);
createControls();
}
/** Which texture coordinate we are editing. */
private JCCheckboxGroup textureCoordinate = null;
private static final int textureValues[] = {
0, 1
};
private static final String[] textureCoords= {
"u", "v"
};
private JCCheckbox applyCharges = null;
private JCCheckbox applyMlp = null;
private JCSpinBox uminSB = null;
private JCSpinBox vminSB = null;
private JCSpinBox umaxSB = null;
private JCSpinBox vmaxSB = null;
private HashMap<JCButton, String> imageHash = new HashMap<JCButton, String>(11);
/** Create the controls for this property editor. */
private void createControls(){
textureCoordinate =
JCCheckbox.makeGroup(textureCoords, textureValues, true);
textureCoordinate.setOrientation(JCCheckboxGroup.VERTICAL);
textureCoordinate.setTitle("Coordinate");
Layout.fill(this, textureCoordinate, 0, 0, 1, 1,
GridBagConstraints.HORIZONTAL);
JCGroupBox properties = UI.groupbox("Properties");
JCButton electrostatic = new JCButton("Electrostatic");
electrostatic.setActionCommand("electrostatic");
electrostatic.addActionListener(this);
Layout.fill(properties, electrostatic, 1, 1, 1, 1,
GridBagConstraints.HORIZONTAL);
applyCharges = new JCCheckbox("Charge");
applyCharges.setState(1);
applyCharges.setIndicator(JCCheckbox.INDICATOR_CHECK);
Layout.fill(properties, applyCharges, 1, 2, 1, 1,
GridBagConstraints.HORIZONTAL);
JCButton mlp = new JCButton("Lipophilicity");
mlp.setActionCommand("lipophilicity");
mlp.addActionListener(this);
Layout.fill(properties, mlp, 1, 3, 1, 1,
GridBagConstraints.HORIZONTAL);
applyMlp = new JCCheckbox("Contributions");
applyMlp.setState(1);
applyMlp.setIndicator(JCCheckbox.INDICATOR_CHECK);
Layout.fill(properties, applyMlp, 1, 4, 1, 1,
GridBagConstraints.HORIZONTAL);
JCButton distance = new JCButton("Distance");
distance.setActionCommand("distance");
distance.addActionListener(this);
Layout.fill(properties, distance, 1, 5, 1, 1,
GridBagConstraints.HORIZONTAL);
JCButton curvature = new JCButton("Curvature");
curvature.setActionCommand("curvature");
curvature.addActionListener(this);
Layout.fill(properties, curvature, 1, 6, 1, 1,
GridBagConstraints.HORIZONTAL);
JCButton atomColors = new JCButton("Atom colors");
atomColors.setActionCommand("atom_colors");
atomColors.addActionListener(this);
Layout.fill(properties, atomColors, 1, 7, 1, 1,
GridBagConstraints.HORIZONTAL);
JCButton clipObject = new JCButton("Clip");
clipObject.setActionCommand("clip_object");
clipObject.addActionListener(this);
Layout.fill(properties, clipObject, 1, 8, 1, 1,
GridBagConstraints.HORIZONTAL);
Layout.fill(this, properties, 1, 0, 1, 2,
GridBagConstraints.VERTICAL);
//Texture ranges
JCGroupBox rangeGB = UI.groupbox("Ranges");
JCLabel uminLabel = new JCLabel("umin");
uminSB = UI.spinbox(5, -10000, 10000, 0, 2, 5, this);
JCLabel umaxLabel = new JCLabel("umax");
umaxSB = UI.spinbox(5, -10000, 10000, 0, 2, 5, this);
JCLabel vminLabel = new JCLabel("vmin");
vminSB = UI.spinbox(5, -10000, 10000, 0, 2, 5, this);
JCLabel vmaxLabel = new JCLabel("vmax");
vmaxSB = UI.spinbox(5, -10000, 10000, 0, 2, 5, this);
Layout.nofill(rangeGB, uminLabel, 0, 0);
Layout.nofill(rangeGB, uminSB, 1, 0);
Layout.nofill(rangeGB, umaxLabel, 2, 0);
Layout.nofill(rangeGB, umaxSB, 3, 0);
Layout.nofill(rangeGB, vminLabel, 0, 1);
Layout.nofill(rangeGB, vminSB, 1, 1);
Layout.nofill(rangeGB, vmaxLabel, 2, 1);
Layout.nofill(rangeGB, vmaxSB, 3, 1);
Layout.fill(this, rangeGB, 0, 2, 2, 1,
GridBagConstraints.HORIZONTAL);
JCGroupBox textureGB = UI.groupbox("Textures");
Layout.fill(this, textureGB, 0, 1, 1, 1,
GridBagConstraints.BOTH);
JCScrolledWindow textureList = new JCScrolledWindow();
textureList.setScrollbarDisplay(JCScrolledWindow.DISPLAY_VERTICAL_ONLY);
JCContainer textureContainer = new JCContainer();
textureContainer.setLayout(new JCGridLayout(0, 3));
textureList.add(textureContainer);
Layout.fill(textureGB, textureList, 1, 1, 5, 1, GridBagConstraints.BOTH);
JCActionListener tal = new JCActionListener(){
public void actionPerformed(JCActionEvent e){
String texture = imageHash.get(e.getSource());
String textureName = Settings.getString("config", texture);
String textureImage = Settings.getString("config", texture + ".image");
StringBuilder command = new StringBuilder(16);
command.append("texture load '").append(textureName).append("' '").append(textureImage).append("';");
command.append("object '").append(object.getName()).append("' texture '").append(textureName).append("';");
System.out.println("command " + command);
moleculeRenderer.execute(command.toString());
moleculeRenderer.repaint();
}
};
for(int t = 0; t < 10000; t++){
String texture = "texture." + t;
String textureName = Settings.getString("config", texture);
if(textureName == null){
break;
}
String smallImageTag = "texture." + t + ".small";
String smallImageName = Settings.getString("config", smallImageTag);
if(smallImageName != null){
Image smallImage = Texture.loadImage(smallImageName);
if(smallImage != null){
MediaTracker mt = new MediaTracker(this);
mt.addImage(smallImage, 1);
try {
mt.waitForAll();
}catch(InterruptedException e){
Log.error("interrupted loading " + smallImageName);
}
JCButton ib = new JCButton(smallImage);
ib.setPreferredSize(16, 16);
ib.setInsets(new Insets(0,0,0,0));
ib.addActionListener(tal);
imageHash.put(ib, texture);
textureContainer.add(ib);
}else{
Log.error("couldn't load image defined by " + smallImageTag);
}
}else{
Log.error("no small image defined by " + texture);
}
}
}
public void spinBoxChangeBegin(JCSpinBoxEvent e){
}
public void spinBoxChangeEnd(JCSpinBoxEvent e){
if(!active) return;
boolean handled = true;
Object source = e.getSource();
StringBuilder command = new StringBuilder(16);
if(source == uminSB || source == umaxSB ||
source == vminSB || source == vmaxSB){
command.append("object '").append(object.getName()).append("' texture ");
if(source == uminSB || source == umaxSB){
command.append("urange ").append(uminSB.getValue()).append(' ').append(umaxSB.getValue());
}else{
command.append("vrange ").append(vminSB.getValue()).append(' ').append(vmaxSB.getValue());
}
command.append(';');
}else{
handled = false;
}
if(handled){
moleculeRenderer.execute(command.toString());
moleculeRenderer.moleculeViewer.dirtyRepaint();
}
}
/** Handle actions on the user interface. */
public void actionPerformed(JCActionEvent e){
if(!active) return;
String actionCommand = e.getActionCommand();
boolean handled = true;
String name = "'" + object.getName() + "'";
int tc = textureCoordinate.getValue();
String texCoord = textureCoords[tc];
boolean needTexture = true;
StringBuilder command = new StringBuilder(100);
if("distance".equals(actionCommand)){
command.append("object ").append(name).append(" texture distance ")
.append(texCoord).append(" default;object ").append(name)
.append(" texture ").append(texCoord).append("div 8.0;");
if(tc == 0){
command.append("texture load white 'white.jpg';object ")
.append(name).append(" texture white;");
}
needTexture = false;
}else if("electrostatic".equals(actionCommand)){
if(applyCharges.getState() == 1){
command.append("run 'charge.properties';");
}
command.append("object ").append(name)
.append(" texture electrostatic ").append(texCoord)
.append(" 12.0 default;texture load rwb 'images/textures/rwb.jpg';")
.append("object ").append(name).append(" texture rwb;");
needTexture = false;
}else if("lipophilicity".equals(actionCommand)){
if(applyMlp.getState() == 1){
command.append("run 'lipophilicity.properties';");
}
command.append("object ").append(name)
.append(" texture lipophilicity ").append(texCoord)
.append(" 7.0 default;texture load molcad 'images/textures/red2blue.jpg';object ")
.append(name).append(" texture molcad;");
needTexture = false;
}else if("curvature".equals(actionCommand)){
command.append("object ").append(name).append(" texture curvature ")
.append(texCoord).append(" 6 default;object ").append(name)
.append(" texture ").append(texCoord)
.append("div 1.0;texture load rwb 'images/textures/rwb.jpg';object ")
.append(name).append(" texture rwb;");
needTexture = false;
}else if("atom_colors".equals(actionCommand)){
command.append("object ").append(name).append(" -map { current };");
}else if("clip_object".equals(actionCommand)){
command.append("object ").append(name).append(" clip ").append(texCoord).append(";");
needTexture = false;
}else{
handled = false;
}
if(needTexture){
moleculeRenderer.execute("texture close simple;");
moleculeRenderer.execute("object " + name + " texture close;");
}
if(handled){
moleculeRenderer.execute(command.toString());
setMinMax();
moleculeRenderer.moleculeViewer.dirtyRepaint();
return;
}
}
/** Set the min max values for this object. */
private void setMinMax(){
active = false;
// add 0.5 to make rounding better when converting to int
double umin = object.getInverseTexture(Tmesh.UTexture, 0.0);
uminSB.setIntValue((int)(0.5 + 100.*umin));
double umax = object.getInverseTexture(Tmesh.UTexture, 1.0);
umaxSB.setIntValue((int)(0.5 + 100.*umax));
double vmin = object.getInverseTexture(Tmesh.VTexture, 0.0);
vminSB.setIntValue((int)(0.5 + 100.*vmin));
double vmax = object.getInverseTexture(Tmesh.VTexture, 1.0);
vmaxSB.setIntValue((int)(0.5 + 100.*vmax));
active = true;
}
/* Implementation of WindowListener. */
public void windowClosing(WindowEvent e){
setVisible(false);
}
public void windowActivated(WindowEvent e){ }
public void windowClosed(WindowEvent e){ }
public void windowDeactivated(WindowEvent e){ }
public void windowDeiconified(WindowEvent e){ }
public void windowIconified(WindowEvent e){ }
public void windowOpened(WindowEvent e){ }
}