mirror of
https://github.com/Julow/Unexpected-Keyboard.git
synced 2024-11-24 16:23:14 +01:00
Move layout definitions into srcs/layouts
This separates the layout definitions from the special layouts (bottom_row, greekmath) and other unrelated files (method, settings). This is also a more intuitive location for layouts and make the resource directory easier to navigate. Under the hood, layouts are copied back into build/generated-resources/xml.
This commit is contained in:
parent
bef29da3de
commit
ad7314a016
@ -88,14 +88,15 @@ Github secret named `DEBUG_KEYSTORE`.
|
|||||||
|
|
||||||
### Adding a layout
|
### Adding a layout
|
||||||
|
|
||||||
Layouts are defined in XML, see `res/xml/latn_qwerty_us.xml`.
|
Layouts are defined in XML, see `srcs/layouts/latn_qwerty_us.xml`.
|
||||||
An online tool for editing layout files written by @Lixquid is available
|
An online tool for editing layout files written by @Lixquid is available
|
||||||
[here](https://unexpected-keyboard-layout-editor.lixquid.com/).
|
[here](https://unexpected-keyboard-layout-editor.lixquid.com/).
|
||||||
|
|
||||||
Makes sure to specify the `name` attribute like in `latn_qwerty_us.xml`,
|
Makes sure to specify the `name` attribute like in `latn_qwerty_us.xml`,
|
||||||
otherwise the layout won't be added to the app.
|
otherwise the layout won't be added to the app.
|
||||||
|
|
||||||
The layout file must be placed in the `res/xml/` directory and named according to:
|
The layout file must be placed in the `srcs/layouts` directory and named
|
||||||
|
according to:
|
||||||
- script (`latn` for latin, etc..)
|
- script (`latn` for latin, etc..)
|
||||||
- layout name (eg. the name of a standard)
|
- layout name (eg. the name of a standard)
|
||||||
- country code (or language code if more adequate)
|
- country code (or language code if more adequate)
|
||||||
|
27
build.gradle
27
build.gradle
@ -115,17 +115,13 @@ tasks.register('genLayoutsList') {
|
|||||||
|
|
||||||
tasks.register('checkKeyboardLayouts') {
|
tasks.register('checkKeyboardLayouts') {
|
||||||
println "\nChecking layouts"
|
println "\nChecking layouts"
|
||||||
new ByteArrayOutputStream().withStream { bos ->
|
exec {
|
||||||
exec {
|
def layouts = new File(projectDir, "srcs/layouts").listFiles().findAll {
|
||||||
def layouts = new File(projectDir, "res/xml").listFiles().findAll {
|
it.name.endsWith(".xml")
|
||||||
it.isFile() && it.name.endsWith(".xml")
|
|
||||||
}
|
|
||||||
workingDir = projectDir
|
|
||||||
commandLine("python", "check_layout.py", *layouts)
|
|
||||||
standardOutput = bos
|
|
||||||
}
|
}
|
||||||
|
workingDir = projectDir
|
||||||
new File(projectDir, "check_layout.output").write(bos.toString())
|
commandLine("python", "check_layout.py", *layouts)
|
||||||
|
standardOutput = new FileOutputStream("${projectDir}/check_layout.output")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,6 +136,7 @@ tasks.register('syncTranslations') {
|
|||||||
tasks.named("preBuild") {
|
tasks.named("preBuild") {
|
||||||
dependsOn += "initDebugKeystore"
|
dependsOn += "initDebugKeystore"
|
||||||
dependsOn += "copyRawQwertyUS"
|
dependsOn += "copyRawQwertyUS"
|
||||||
|
dependsOn += "copyLayoutDefinitions"
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register('initDebugKeystore') {
|
tasks.register('initDebugKeystore') {
|
||||||
@ -156,7 +153,15 @@ tasks.register('initDebugKeystore') {
|
|||||||
tasks.register('copyRawQwertyUS')
|
tasks.register('copyRawQwertyUS')
|
||||||
{
|
{
|
||||||
copy {
|
copy {
|
||||||
from "res/xml/latn_qwerty_us.xml"
|
from "srcs/layouts/latn_qwerty_us.xml"
|
||||||
into "build/generated-resources/raw"
|
into "build/generated-resources/raw"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.register('copyLayoutDefinitions')
|
||||||
|
{
|
||||||
|
copy {
|
||||||
|
from "srcs/layouts"
|
||||||
|
into "build/generated-resources/xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# Generates the list of layouts in res/values/layouts.xml from the layout files
|
# Generates the list of layouts in res/values/layouts.xml from the layout files
|
||||||
# in res/xml. Every layouts must have a 'name' attribute to be listed.
|
# in srcs/layouts. Every layouts must have a 'name' attribute to be listed.
|
||||||
|
|
||||||
import itertools as it
|
import itertools as it
|
||||||
import sys, os, glob
|
import sys, os, glob
|
||||||
@ -11,11 +11,6 @@ import xml.etree.ElementTree as XML
|
|||||||
# are sorted alphabetically.
|
# are sorted alphabetically.
|
||||||
FIRST_LAYOUTS = [ "latn_qwerty_us", "latn_colemak", "latn_dvorak" ]
|
FIRST_LAYOUTS = [ "latn_qwerty_us", "latn_colemak", "latn_dvorak" ]
|
||||||
|
|
||||||
# File names that are known not to be layouts. Avoid warning about them.
|
|
||||||
KNOWN_NOT_LAYOUT = set([
|
|
||||||
"number_row", "numpad", "pin", "bottom_row", "settings", "method",
|
|
||||||
"greekmath", "numeric" ])
|
|
||||||
|
|
||||||
# Read a layout from a file. Returns [None] if [fname] is not a layout.
|
# Read a layout from a file. Returns [None] if [fname] is not a layout.
|
||||||
def read_layout(fname):
|
def read_layout(fname):
|
||||||
root = XML.parse(fname).getroot()
|
root = XML.parse(fname).getroot()
|
||||||
@ -28,9 +23,7 @@ def read_layouts(files):
|
|||||||
for layout_file in files:
|
for layout_file in files:
|
||||||
layout_id, _ = os.path.splitext(os.path.basename(layout_file))
|
layout_id, _ = os.path.splitext(os.path.basename(layout_file))
|
||||||
layout = read_layout(layout_file)
|
layout = read_layout(layout_file)
|
||||||
if layout_id in KNOWN_NOT_LAYOUT:
|
if layout == None:
|
||||||
continue
|
|
||||||
elif layout == None:
|
|
||||||
print("Not a layout file: %s" % layout_file)
|
print("Not a layout file: %s" % layout_file)
|
||||||
elif layout["name"] == None:
|
elif layout["name"] == None:
|
||||||
print("Layout doesn't have a name: %s" % layout_id)
|
print("Layout doesn't have a name: %s" % layout_id)
|
||||||
@ -66,6 +59,6 @@ def generate_arrays(out, layouts):
|
|||||||
XML.indent(root)
|
XML.indent(root)
|
||||||
XML.ElementTree(element=root).write(out, encoding="unicode", xml_declaration=True)
|
XML.ElementTree(element=root).write(out, encoding="unicode", xml_declaration=True)
|
||||||
|
|
||||||
layouts = sort_layouts(read_layouts(glob.glob("res/xml/*.xml")))
|
layouts = sort_layouts(read_layouts(glob.glob("srcs/layouts/*.xml")))
|
||||||
with open("res/values/layouts.xml", "w") as out:
|
with open("res/values/layouts.xml", "w") as out:
|
||||||
generate_arrays(out, layouts)
|
generate_arrays(out, layouts)
|
||||||
|
@ -317,9 +317,9 @@ public final class KeyValue
|
|||||||
{
|
{
|
||||||
switch (name)
|
switch (name)
|
||||||
{
|
{
|
||||||
/* These symbols have special meaning when in `res/xml` and are escaped in
|
/* These symbols have special meaning when in `srcs/layouts` and are
|
||||||
standard layouts. The backslash is not stripped when parsed from the
|
escaped in standard layouts. The backslash is not stripped when parsed
|
||||||
custom layout option. */
|
from the custom layout option. */
|
||||||
case "\\?": return makeStringKey("?");
|
case "\\?": return makeStringKey("?");
|
||||||
case "\\#": return makeStringKey("#");
|
case "\\#": return makeStringKey("#");
|
||||||
case "\\@": return makeStringKey("@");
|
case "\\@": return makeStringKey("@");
|
||||||
|
@ -245,7 +245,7 @@ public class LayoutsPreference extends ListGroupPreference<LayoutsPreference.Lay
|
|||||||
public SystemLayout() {}
|
public SystemLayout() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The name of a layout defined in [res/xml]. */
|
/** The name of a layout defined in [srcs/layouts]. */
|
||||||
public static final class NamedLayout implements Layout
|
public static final class NamedLayout implements Layout
|
||||||
{
|
{
|
||||||
public final String name;
|
public final String name;
|
||||||
|
Loading…
Reference in New Issue
Block a user