mirror of
https://github.com/Julow/Unexpected-Keyboard.git
synced 2025-06-19 08:16:59 +02:00
Per-layout shift modmap
Specify the behavior of shift for a layout. This is intended for locales that use the same alphabet but have different capital letters (eg. Bengali). The modmap is defined like this: <keyboard> <modmap> <shift a="a" b="A"/> </modmap> </keyboard>
This commit is contained in:
parent
d2a92795e9
commit
22d407c46a
@ -123,6 +123,15 @@ public class Keyboard2View extends View
|
|||||||
|
|
||||||
public KeyValue modifyKey(KeyValue k, Pointers.Modifiers mods)
|
public KeyValue modifyKey(KeyValue k, Pointers.Modifiers mods)
|
||||||
{
|
{
|
||||||
|
if (_keyboard.modmap != null)
|
||||||
|
{
|
||||||
|
if (mods.has(KeyValue.Modifier.SHIFT))
|
||||||
|
{
|
||||||
|
KeyValue km = _keyboard.modmap.shift.get(k);
|
||||||
|
if (km != null)
|
||||||
|
return km;
|
||||||
|
}
|
||||||
|
}
|
||||||
return KeyModifier.modify(k, mods);
|
return KeyModifier.modify(k, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +381,7 @@ public class Keyboard2View extends View
|
|||||||
|
|
||||||
private void drawLabel(Canvas canvas, KeyValue kv, float x, float y, float keyH, boolean isKeyDown)
|
private void drawLabel(Canvas canvas, KeyValue kv, float x, float y, float keyH, boolean isKeyDown)
|
||||||
{
|
{
|
||||||
kv = KeyModifier.modify(kv, _mods);
|
kv = modifyKey(kv, _mods);
|
||||||
if (kv == null)
|
if (kv == null)
|
||||||
return;
|
return;
|
||||||
float textSize = scaleTextSize(kv, _config.labelTextSize, keyH);
|
float textSize = scaleTextSize(kv, _config.labelTextSize, keyH);
|
||||||
@ -388,7 +397,7 @@ public class Keyboard2View extends View
|
|||||||
{
|
{
|
||||||
Paint.Align a = LABEL_POSITION_H[sub_index];
|
Paint.Align a = LABEL_POSITION_H[sub_index];
|
||||||
Vertical v = LABEL_POSITION_V[sub_index];
|
Vertical v = LABEL_POSITION_V[sub_index];
|
||||||
kv = KeyModifier.modify(kv, _mods);
|
kv = modifyKey(kv, _mods);
|
||||||
if (kv == null)
|
if (kv == null)
|
||||||
return;
|
return;
|
||||||
float textSize = scaleTextSize(kv, _config.sublabelTextSize, keyH);
|
float textSize = scaleTextSize(kv, _config.sublabelTextSize, keyH);
|
||||||
|
@ -21,13 +21,15 @@ class KeyboardData
|
|||||||
public final float keysWidth;
|
public final float keysWidth;
|
||||||
/** Total height of the keyboard. */
|
/** Total height of the keyboard. */
|
||||||
public final float keysHeight;
|
public final float keysHeight;
|
||||||
|
/** Might be null. */
|
||||||
|
public final Modmap modmap;
|
||||||
|
|
||||||
public KeyboardData mapKeys(MapKey f)
|
public KeyboardData mapKeys(MapKey f)
|
||||||
{
|
{
|
||||||
ArrayList<Row> rows_ = new ArrayList<Row>();
|
ArrayList<Row> rows_ = new ArrayList<Row>();
|
||||||
for (Row r : rows)
|
for (Row r : rows)
|
||||||
rows_.add(r.mapKeys(f));
|
rows_.add(r.mapKeys(f));
|
||||||
return new KeyboardData(rows_, keysWidth);
|
return new KeyboardData(rows_, keysWidth, modmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add keys from the given iterator into the keyboard. Extra keys are added
|
/** Add keys from the given iterator into the keyboard. Extra keys are added
|
||||||
@ -47,7 +49,7 @@ class KeyboardData
|
|||||||
for (int c = 1; c <= 4; c++)
|
for (int c = 1; c <= 4; c++)
|
||||||
addExtraKeys_to_row(rows, k, r, c);
|
addExtraKeys_to_row(rows, k, r, c);
|
||||||
}
|
}
|
||||||
return new KeyboardData(rows, keysWidth);
|
return new KeyboardData(rows, keysWidth, modmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardData addNumPad()
|
public KeyboardData addNumPad()
|
||||||
@ -70,14 +72,15 @@ class KeyboardData
|
|||||||
}
|
}
|
||||||
extendedRows.add(new Row(keys, row.height, row.shift));
|
extendedRows.add(new Row(keys, row.height, row.shift));
|
||||||
}
|
}
|
||||||
return new KeyboardData(extendedRows, compute_max_width(extendedRows));
|
return new
|
||||||
|
KeyboardData(extendedRows, compute_max_width(extendedRows), modmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardData addNumberRow()
|
public KeyboardData addNumberRow()
|
||||||
{
|
{
|
||||||
ArrayList<Row> rows_ = new ArrayList<Row>(this.rows);
|
ArrayList<Row> rows_ = new ArrayList<Row>(this.rows);
|
||||||
rows_.add(0, number_row.updateWidth(keysWidth));
|
rows_.add(0, number_row.updateWidth(keysWidth));
|
||||||
return new KeyboardData(rows_, keysWidth);
|
return new KeyboardData(rows_, keysWidth, modmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Key findKeyWithValue(KeyValue kv)
|
public Key findKeyWithValue(KeyValue kv)
|
||||||
@ -173,12 +176,25 @@ class KeyboardData
|
|||||||
boolean add_bottom_row = attribute_bool(parser, "bottom_row", true);
|
boolean add_bottom_row = attribute_bool(parser, "bottom_row", true);
|
||||||
float specified_kw = attribute_float(parser, "width", 0f);
|
float specified_kw = attribute_float(parser, "width", 0f);
|
||||||
ArrayList<Row> rows = new ArrayList<Row>();
|
ArrayList<Row> rows = new ArrayList<Row>();
|
||||||
while (expect_tag(parser, "row"))
|
Modmap modmap = null;
|
||||||
rows.add(Row.parse(parser));
|
while (next_tag(parser))
|
||||||
|
{
|
||||||
|
switch (parser.getName())
|
||||||
|
{
|
||||||
|
case "row":
|
||||||
|
rows.add(Row.parse(parser));
|
||||||
|
break;
|
||||||
|
case "modmap":
|
||||||
|
modmap = Modmap.parse(parser);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Unknown tag: " + parser.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
float kw = (specified_kw != 0f) ? specified_kw : compute_max_width(rows);
|
float kw = (specified_kw != 0f) ? specified_kw : compute_max_width(rows);
|
||||||
if (add_bottom_row)
|
if (add_bottom_row)
|
||||||
rows.add(bottom_row.updateWidth(kw));
|
rows.add(bottom_row.updateWidth(kw));
|
||||||
return new KeyboardData(rows, kw);
|
return new KeyboardData(rows, kw, modmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float compute_max_width(List<Row> rows)
|
private static float compute_max_width(List<Row> rows)
|
||||||
@ -196,12 +212,13 @@ class KeyboardData
|
|||||||
return Row.parse(parser);
|
return Row.parse(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected KeyboardData(List<Row> rows_, float kw)
|
protected KeyboardData(List<Row> rows_, float kw, Modmap mm)
|
||||||
{
|
{
|
||||||
float kh = 0.f;
|
float kh = 0.f;
|
||||||
for (Row r : rows_)
|
for (Row r : rows_)
|
||||||
kh += r.height + r.shift;
|
kh += r.height + r.shift;
|
||||||
rows = rows_;
|
rows = rows_;
|
||||||
|
modmap = mm;
|
||||||
keysWidth = kw;
|
keysWidth = kw;
|
||||||
keysHeight = kh;
|
keysHeight = kh;
|
||||||
}
|
}
|
||||||
@ -415,10 +432,37 @@ class KeyboardData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Modmap
|
||||||
|
{
|
||||||
|
public final Map<KeyValue, KeyValue> shift;
|
||||||
|
|
||||||
|
public Modmap(Map<KeyValue, KeyValue> s)
|
||||||
|
{
|
||||||
|
shift = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Modmap parse(XmlPullParser parser) throws Exception
|
||||||
|
{
|
||||||
|
HashMap<KeyValue, KeyValue> shift = new HashMap<KeyValue, KeyValue>();
|
||||||
|
while (expect_tag(parser, "shift"))
|
||||||
|
parse_mapping(parser, shift);
|
||||||
|
return new Modmap(shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parse_mapping(XmlPullParser parser, Map<KeyValue, KeyValue> dst) throws Exception
|
||||||
|
{
|
||||||
|
KeyValue a = KeyValue.getKeyByName(parser.getAttributeValue(null, "a"));
|
||||||
|
KeyValue b = KeyValue.getKeyByName(parser.getAttributeValue(null, "b"));
|
||||||
|
while (parser.next() != XmlPullParser.END_TAG)
|
||||||
|
continue;
|
||||||
|
dst.put(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Parsing utils */
|
/** Parsing utils */
|
||||||
|
|
||||||
/** Returns [false] on [END_DOCUMENT] or [END_TAG], [true] otherwise. */
|
/** Returns [false] on [END_DOCUMENT] or [END_TAG], [true] otherwise. */
|
||||||
private static boolean expect_tag(XmlPullParser parser, String name) throws Exception
|
private static boolean next_tag(XmlPullParser parser) throws Exception
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
do
|
do
|
||||||
@ -428,8 +472,16 @@ class KeyboardData
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (status != XmlPullParser.START_TAG);
|
while (status != XmlPullParser.START_TAG);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns [false] on [END_DOCUMENT] or [END_TAG], [true] otherwise. */
|
||||||
|
private static boolean expect_tag(XmlPullParser parser, String name) throws Exception
|
||||||
|
{
|
||||||
|
if (!next_tag(parser))
|
||||||
|
return false;
|
||||||
if (!parser.getName().equals(name))
|
if (!parser.getName().equals(name))
|
||||||
throw new Exception("Unknow tag: " + parser.getName());
|
throw new Exception("Unknown tag: " + parser.getName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,6 +478,10 @@ public final class Pointers implements Handler.Callback
|
|||||||
|
|
||||||
public KeyValue.Modifier get(int i) { return _mods[_size - 1 - i]; }
|
public KeyValue.Modifier get(int i) { return _mods[_size - 1 - i]; }
|
||||||
public int size() { return _size; }
|
public int size() { return _size; }
|
||||||
|
public boolean has(KeyValue.Modifier m)
|
||||||
|
{
|
||||||
|
return (Arrays.binarySearch(_mods, 0, _size, m) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() { return Arrays.hashCode(_mods); }
|
public int hashCode() { return Arrays.hashCode(_mods); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user