org.jmol.viewer.binding.Binding Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jmol Show documentation
Show all versions of jmol Show documentation
Jmol: an open-source Java viewer for chemical structures in 3D
package org.jmol.viewer.binding;
import javajs.awt.event.Event;
import javajs.util.AU;
import javajs.util.Lst;
import javajs.util.PT;
import javajs.util.SB;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import org.jmol.api.Interface;
import org.jmol.util.Escape;
import org.jmol.util.Logger;
import org.jmol.viewer.Viewer;
abstract public class Binding {
// 2 1 0
// 0 9876 5432 1098 7654 3210
// x shift
// x ctrl
// x alt
// x wheel
// x left
// x middle (same as alt)
// x right
// x x left-right (Apple COMMAND)
// x xx button_mask
// xx xxxx button_modifier_mask
// 2 1 0
// 0 9876 5432 1098 7654 3210
// x single
// x double
// xx click_mask
// 2 1 0
// 0 9876 5432 1098 7654 3210
// x down
// x drag
// x up
// x click
// xxxx mode_mask
public final static int LEFT = Event.MOUSE_LEFT;
public final static int MIDDLE = Event.MOUSE_MIDDLE;
public final static int RIGHT = Event.MOUSE_RIGHT;
public final static int WHEEL = Event.MOUSE_WHEEL;
public final static int ALT = Event.ALT_MASK; // MIDDLE and ALT are the same
public final static int CTRL = Event.CTRL_MASK;
public final static int SHIFT = Event.SHIFT_MASK;
public final static int CTRL_ALT = Event.CTRL_ALT;
public final static int CTRL_SHIFT = Event.CTRL_SHIFT;
public final static int MAC_COMMAND = Event.MAC_COMMAND;
public final static int BUTTON_MASK = Event.BUTTON_MASK;
public final static int BUTTON_MODIFIER_MASK = CTRL | SHIFT | LEFT | MIDDLE | RIGHT | WHEEL;
public final static int SINGLE = 1 << 8;
public final static int DOUBLE = 2 << 8;
public final static int COUNT_MASK = SINGLE | DOUBLE;
public final static int DOWN = 1 << 12;
public final static int DRAG = 2 << 12;
public final static int UP = 4 << 12;
public final static int CLICK = 8 << 12;
public final static int MODE_MASK = DOWN | DRAG | UP | CLICK;
public static int getMouseAction(int clickCount, int modifiers, int mode) {
if (clickCount > 2)
clickCount = 2;
switch (clickCount) {
case 0:
break;
case 1:
clickCount = SINGLE;
break;
default:
clickCount = DOUBLE;
}
switch (mode) {
case Event.PRESSED:
mode = DOWN;
break;
case Event.DRAGGED:
mode = DRAG;
break;
case Event.RELEASED:
mode = UP;
break;
case Event.CLICKED:
mode = CLICK;
break;
case Event.WHEELED:
mode = WHEEL;
}
return (modifiers & BUTTON_MODIFIER_MASK) | clickCount | mode;
}
/**
* create an action code from a string such as "CTRL-LEFT-double click"
*
* @param desc
* @return action code
*/
public static int getMouseActionStr(String desc) {
if (desc == null)
return 0;
int mouseAction = 0;
desc = desc.toUpperCase();
if (desc.indexOf("MIDDLE") >= 0)
mouseAction = MIDDLE;
else if (desc.indexOf("RIGHT") >= 0)
mouseAction = RIGHT;
else if (desc.indexOf("WHEEL") >= 0)
mouseAction = WHEEL;
else
mouseAction = LEFT;
if (desc.indexOf("DOWN") >= 0)
mouseAction |= DOWN;
else if (desc.indexOf("DRAG") >= 0)
mouseAction |= DRAG;
else if (desc.indexOf("UP") >= 0)
mouseAction |= UP;
else if (mouseAction != WHEEL)
mouseAction |= CLICK;
if (mouseAction != WHEEL && desc.indexOf("DOUBLE") >= 0)
mouseAction |= DOUBLE;
else if (mouseAction > 0)
mouseAction |= SINGLE;
if (mouseAction != (SINGLE | WHEEL) && desc.indexOf("ALT") >= 0)
mouseAction |= ALT;
if (desc.indexOf("CTRL") >= 0)
mouseAction |= CTRL;
if (desc.indexOf("SHIFT") >= 0)
mouseAction |= SHIFT;
return mouseAction;
}
public static int getButtonMods(int mouseAction) {
return mouseAction & BUTTON_MODIFIER_MASK;
}
public static int getClickCount(int mouseAction) {
return (mouseAction & COUNT_MASK) >> 8;
}
public static String getMouseActionName(int mouseAction, boolean addSortCode) {
SB sb = new SB();
if (mouseAction == 0)
return "";
boolean isMiddle = (includes(mouseAction, MIDDLE)
&& !includes(mouseAction, LEFT) && !includes(mouseAction, RIGHT));
char[] code = " ".toCharArray();
if (includes(mouseAction, CTRL)) {
sb.append("CTRL+");
code[5] = 'C';
}
if (!isMiddle && includes(mouseAction, ALT)) {
sb.append("ALT+");
code[4] = 'A';
}
if (includes(mouseAction, SHIFT)) {
sb.append("SHIFT+");
code[3] = 'S';
}
if (includes(mouseAction, LEFT)) {
code[2] = 'L';
sb.append("LEFT");
} else if (includes(mouseAction, RIGHT)) {
code[2] = 'R';
sb.append("RIGHT");
} else if (isMiddle) {
code[2] = 'M';
sb.append("MIDDLE");
} else if (includes(mouseAction, WHEEL)) {
code[2] = 'W';
sb.append("WHEEL");
}
if (includes(mouseAction, DOUBLE)) {
sb.append("+double");
code[1] = '2';
}
if (includes(mouseAction, DOWN)) {
sb.append("+down");
code[0] = '1';
} else if (includes(mouseAction, DRAG)) {
sb.append("+drag");
code[0] = '2';
} else if (includes(mouseAction, UP)) {
sb.append("+up");
code[0] = '3';
} else if (includes(mouseAction, CLICK)) {
sb.append("+click");
code[0] = '4';
}
return (addSortCode ? new String(code) + ":" + sb.toString() : sb
.toString());
}
public String name;
private Map bindings = new Hashtable();
public Map getBindings() {
return bindings;
}
public Binding() {
}
public final void bindAction(int mouseAction, int jmolAction) {
//System.out.println("binding " + mouseAction + " " + getMouseActionName(mouseAction, false) + "\t" + jmolAction);
addBinding(mouseAction + "\t" + jmolAction, new int[] {mouseAction, jmolAction});
}
public void bindName(int mouseAction, String name) {
addBinding(mouseAction + "\t", Boolean.TRUE);
addBinding(mouseAction + "\t" + name, new String[] { getMouseActionName(mouseAction, false), name });
}
public final void unbindAction(int mouseAction, int jmolAction) {
if (mouseAction == 0)
unbindJmolAction(jmolAction);
else
removeBinding(null, mouseAction + "\t" + jmolAction);
}
public final void unbindName(int mouseAction, String name) {
if (name == null)
unbindMouseAction(mouseAction);
else
removeBinding(null, mouseAction + "\t" + name);
}
public final void unbindJmolAction(int jmolAction) {
Iterator e = bindings.keySet().iterator();
String skey = "\t" + jmolAction;
while (e.hasNext()) {
String key = e.next();
if (key.endsWith(skey))
removeBinding(e, key);
}
}
private void addBinding(String key, Object value) {
if (Logger.debugging)
Logger.debug("adding binding " + key + "\t==\t" + Escape.e(value));
bindings.put(key, value);
}
private void removeBinding(Iterator e, String key) {
if (Logger.debugging)
Logger.debug("removing binding " + key);
if (e == null)
bindings.remove(key);
else
e.remove();
}
public final void unbindUserAction(String script) {
Iterator e = bindings.keySet().iterator();
String skey = "\t" + script;
while (e.hasNext()) {
String key = e.next();
if (key.endsWith(skey))
removeBinding(e, key);
}
}
public final void unbindMouseAction(int mouseAction) {
Iterator e = bindings.keySet().iterator();
String skey = mouseAction + "\t";
while (e.hasNext()) {
String key = e.next();
if (key.startsWith(skey))
removeBinding(e, key);
}
}
public final boolean isBound(int mouseAction, int jmolAction) {
//System.out.println("checking isBound " + mouseAction + " " + getMouseActionName(mouseAction, false) + "\t" + jmolAction);
return bindings.containsKey(mouseAction + "\t" + jmolAction);
}
public final boolean isUserAction(int mouseAction) {
return bindings.containsKey(mouseAction + "\t");
}
@SuppressWarnings("unchecked")
public String getBindingInfo(String[] actionInfo, String[] actionNames,
String qualifiers) {
SB sb = new SB();
String qlow = (qualifiers == null || qualifiers.equalsIgnoreCase("all") ? null
: qualifiers.toLowerCase());
Lst[] names = new Lst[actionInfo.length];
Lst user = new Lst();
for (Object obj : bindings.values()) {
if (obj instanceof Boolean) {
// ignore
} else if (AU.isAS(obj)) {
String action = ((String[]) obj)[0];
String script = ((String[]) obj)[1];
if (qlow == null || qlow.indexOf("user") >= 0 || action.indexOf(qlow) >= 0 || script.indexOf(qlow) >= 0)
user.addLast((String[]) obj);
} else {
// we cannot test using AU.isAI() here because of a Java2Script compiler error
// in relation to new int[] {.....} BH 2015.02.03
int[] info = (int[]) obj;
int i = info[1];
if (names[i] == null)
names[i] = new Lst();
String name = getMouseActionName(info[0], true);
if (qlow == null
|| (actionNames[i] + ";" + actionInfo[i] + ";" + name).toLowerCase().indexOf(qlow) >= 0)
names[i].addLast(name);
}
}
for (int i = 0; i < actionInfo.length; i++) {
int n;
if (names[i] == null || (n = names[i].size()) == 0)
continue;
addInfo(sb, names[i].toArray(new String[n]), actionNames[i], actionInfo[i]);
}
for (int i = 0; i < user.size(); i++) {
String[] info = user.get(i);
addInfo(sb, new String[] {"USER:::" + info[0]}, "user-defined", info[1]);
}
return sb.toString();
}
private void addInfo(SB sb, String[] list, String name, String info) {
Arrays.sort(list);
PT.leftJustify(sb, " ", name);
sb.append("\t");
String sep = "";
int len = sb.length();
for (int j = 0; j < list.length; j++) {
sb.append(sep).append(list[j].substring(7));
sep = ", ";
}
len = sb.length() - len;
if (len < 20)
sb.append(" ".substring(0, 20 - len));
sb.append("\t").append(info).appendC('\n');
}
private static boolean includes(int mouseAction, int mod) {
return ((mouseAction & mod) == mod);
}
public static Binding newBinding(Viewer vwr, String name) {
return (Binding) Interface.getInterface("org.jmol.viewer.binding." + name + "Binding", vwr, "script");
}
}