blob: 793b5c569bed03c8c666b05e97e09e12fbc9416b [file] [log] [blame]
package org.unicode.cldr.draft.keyboard;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Functions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* Modifier keys used in the LDML Keyboard XML representation. A modifier key is pressed to change
* the behavior of the keyboard. For example, pressing the Shift key on most Latin keyboards
* produces upper-case variants of the characters.
*
* <p>
* It is important NOT to change the ordering of the declared enum members because this enumeration
* is used for sorting purposes.
*/
public enum ModifierKey {
COMMAND(Variant.NONE, "cmd"),
CONTROL(Variant.PARENT, "ctrl"),
CONTROL_LEFT(Variant.LEFT, "ctrl"),
CONTROL_RIGHT(Variant.RIGHT, "ctrl"),
ALT(Variant.PARENT, "alt"),
ALT_LEFT(Variant.LEFT, "alt"),
ALT_RIGHT(Variant.RIGHT, "alt"),
OPTION(Variant.PARENT, "opt"),
OPTION_LEFT(Variant.LEFT, "opt"),
OPTION_RIGHT(Variant.RIGHT, "opt"),
CAPSLOCK(Variant.NONE, "caps"),
SHIFT(Variant.PARENT, "shift"),
SHIFT_LEFT(Variant.LEFT, "shift"),
SHIFT_RIGHT(Variant.RIGHT, "shift");
// Map of modifier key identifiers (obtained by calling toString()) to the modifier key itself.
private static final ImmutableMap<String, ModifierKey> STRING_TO_MODIFIER_KEY = Maps.uniqueIndex(
Lists.newArrayList(ModifierKey.values()), Functions.toStringFunction());
private static final ImmutableSet<ModifierKey> PARENTS = ImmutableSet.of(CONTROL, ALT, OPTION,
SHIFT);
private static final ImmutableSet<ModifierKey> SINGLES = ImmutableSet.of(COMMAND, CAPSLOCK);
private final Variant variant;
private final String keyType;
private ModifierKey(Variant variant, String keyType) {
this.variant = checkNotNull(variant);
this.keyType = checkNotNull(keyType);
}
/** Retrieves a modifier key from its string identifier. */
public static ModifierKey fromString(String string) {
ModifierKey key = STRING_TO_MODIFIER_KEY.get(checkNotNull(string));
checkArgument(key != null, string);
return key;
}
/** Returns all keys that are parent keys. */
public static ImmutableSet<ModifierKey> parents() {
return PARENTS;
}
/** Returns all keys that are neither parent keys or children. */
public static ImmutableSet<ModifierKey> singles() {
return SINGLES;
}
/**
* Returns the matching sibling of this key. For example, if this key is ctrlR return ctrlL. If
* the key has no siblings this method simply returns itself.
*/
public ModifierKey sibling() {
if (variant == Variant.PARENT) {
return this;
}
return fromString(keyType + variant.opposite());
}
/**
* Returns the parent of this key. For example, if this key is ctrlR return ctrl. If the key is
* already a parent key this method simply returns itself.
*/
public ModifierKey parent() {
if (variant == Variant.PARENT) {
return this;
}
return fromString(keyType);
}
/**
* Returns the children of this key. For example if this key is ctrl, return both ctrlL and ctrlR.
* If this is not a parent key, returns an empty list. The left key is always returned first.
*/
public ImmutableList<ModifierKey> children() {
if (variant != Variant.PARENT) {
return ImmutableList.of();
}
return ImmutableList.of(fromString(keyType + Variant.LEFT), fromString(keyType + Variant.RIGHT));
}
@Override public String toString() {
return keyType + variant.value;
}
/** The variant of the key. */
private static enum Variant {
PARENT(""), LEFT("L"), RIGHT("R"), NONE("");
final String value;
Variant(String value) {
this.value = checkNotNull(value);
}
/**
* Return the opposite variant. Only applicable to the left and right variants. Returns itself
* otherwise.
*/
Variant opposite() {
return this == LEFT ? RIGHT : this == RIGHT ? LEFT : this;
}
@Override public String toString() {
return value;
}
}
}