Skip to content

Instantly share code, notes, and snippets.

@MaurizioB
Created February 10, 2021 20:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MaurizioB/43a053575f17eae371a9d7394e66a46e to your computer and use it in GitHub Desktop.
Save MaurizioB/43a053575f17eae371a9d7394e66a46e to your computer and use it in GitHub Desktop.
Qt piano keyboard
{
"be": {
"basic": {
"name": "Belgian",
"include": ["latin","level3.ralt_switch"],
"keys": {
"0": {
"0": "w",
"6": ",",
"7": ";",
"8": ":",
"9": "="
},
"1": {
"0": "q",
"9": "m",
"10": "ù"
},
"2": {
"0": "a",
"1": "z",
"2": "e",
"8": "o",
"10": "ˆ",
"11": "$"
},
"3": {
"0": "&",
"1": "é",
"2": "\"",
"3": "'",
"4": "(",
"5": "§",
"6": "è",
"7": "!",
"8": "ç",
"9": "à",
"10": ")",
"11": "-"
}
}
},
"Sundeadkeys": {
"include": ["be.sundeadkeys"],
"keys": {
}
},
"iso-alternate": {
"name": "Belgian (ISO alternate)",
"include": ["be.basic"],
"keys": {
"0": {
"0": "w",
"6": ","
},
"1": {
"0": "q",
"9": "m"
},
"2": {
"0": "a",
"1": "z"
}
}
},
"nodeadkeys": {
"name": "Belgian (eliminate dead keys)",
"include": ["be.basic"],
"keys": {
"0": {
"6": ",",
"9": "="
},
"1": {
"9": "m",
"10": "ù"
},
"2": {
"10": "^",
"11": "$"
},
"3": {
"11": "-"
}
}
},
"oss": {
"name": "Belgian (alternative)",
"include": ["fr.oss","be.oss_frbe"],
"keys": {
}
},
"oss_Sundeadkeys": {
"include": ["be.oss"],
"keys": {
"0": {
"9": "="
},
"1": {
"10": "ù"
},
"2": {
"10": "ˆ"
},
"3": {
"3": "'"
}
}
},
"oss_frbe": {
"keys": {
"0": {
"9": "="
},
"1": {
"8": "l"
},
"2": {
"10": "ˆ",
"11": "$"
},
"3": {
"0": "&",
"1": "é",
"3": "'",
"4": "(",
"5": "§",
"7": "!",
"8": "ç",
"9": "à",
"10": ")",
"11": "-"
}
}
},
"oss_latin9": {
"name": "Belgian (alternative, Latin-9 only)",
"include": ["fr.oss_latin9","be.oss_frbe","keypad.oss_latin9"],
"keys": {
"0": {
"9": "="
},
"1": {
"8": "l"
},
"2": {
"11": "$"
},
"3": {
"0": "&",
"3": "'",
"4": "(",
"5": "§",
"11": "-"
}
}
},
"oss_sundeadkeys": {
"name": "Belgian (alternative, Sun dead keys)",
"include": ["be.oss_Sundeadkeys"],
"keys": {
}
},
"sundeadkeys": {
"name": "Belgian (Sun dead keys)",
"include": ["be.basic"],
"keys": {
"0": {
"6": ",",
"9": "="
},
"1": {
"10": "ù"
},
"2": {
"10": "ˆ"
}
}
},
"wang": {
"name": "Belgian (Wang model 724 azerty)",
"include": ["be.basic","keypad.legacy_wang"],
"keys": {
}
}
},
"fr": {
"basic": {
"name": "French",
"include": ["latin","level3.ralt_switch"],
"keys": {
"0": {
"0": "w",
"6": ",",
"7": ";",
"8": ":",
"9": "!"
},
"1": {
"0": "q",
"9": "m",
"10": "ù"
},
"2": {
"0": "a",
"1": "z",
"2": "e",
"10": "ˆ",
"11": "$"
},
"3": {
"0": "&",
"1": "é",
"2": "\"",
"3": "'",
"4": "(",
"5": "-",
"6": "è",
"7": "_",
"8": "ç",
"9": "à",
"10": ")",
"11": "="
}
}
},
"Sundeadkeys": {
"include": ["fr.basic"],
"keys": {
"0": {
"6": ","
},
"2": {
"10": "ˆ"
}
}
},
"azerty": {
"name": "French (Azerty)",
"include": ["level3.ralt_switch"],
"keys": {
"0": {
"0": "w",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": ",",
"7": ";",
"8": ":",
"9": "!"
},
"1": {
"0": "q",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": "m",
"10": "ù"
},
"2": {
"0": "a",
"1": "z",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "ˆ",
"11": "$"
},
"3": {
"0": "&",
"1": "é",
"2": "\"",
"3": "'",
"4": "(",
"5": "-",
"6": "è",
"7": "_",
"8": "ç",
"9": "à",
"10": ")",
"11": "="
}
}
},
"bepo": {
"name": "French (Bepo, ergonomic, Dvorak way)",
"include": ["level3.ralt_switch","keypad.oss"],
"keys": {
"0": {
"0": "à",
"1": "y",
"2": "x",
"3": ".",
"4": "k",
"5": "'",
"6": "q",
"7": "g",
"8": "h",
"9": "f"
},
"1": {
"0": "a",
"1": "u",
"2": "i",
"3": "e",
"4": ",",
"5": "c",
"6": "t",
"7": "s",
"8": "r",
"9": "n",
"10": "m"
},
"2": {
"0": "b",
"1": "é",
"2": "p",
"3": "o",
"4": "è",
"5": "ˆ",
"6": "v",
"7": "d",
"8": "l",
"9": "j",
"10": "z",
"11": "w"
},
"3": {
"10": "=",
"11": "%"
}
}
},
"bepo_latin9": {
"name": "French (Bepo, ergonomic, Dvorak way, Latin-9 only)",
"include": ["fr.bepo","keypad.oss_latin9"],
"keys": {
"0": {
"1": "y",
"2": "x",
"3": ".",
"8": "h",
"9": "f"
},
"1": {
"2": "i",
"4": ",",
"5": "c",
"7": "s",
"8": "r",
"10": "m"
},
"2": {
"0": "b",
"1": "é",
"9": "j",
"10": "z",
"11": "w"
},
"3": {
"10": "=",
"11": "%"
}
}
},
"bre": {
"name": "French (Breton)",
"include": ["keypad.oss","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"7": "ñ",
"8": ".",
"9": ","
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": "m",
"10": "ù"
},
"2": {
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "ˆ",
"11": "/"
},
"3": {
"0": "&",
"1": "é",
"2": "\"",
"3": "'",
"4": "(",
"5": "-",
"6": "è",
"7": "_",
"8": "ç",
"9": "à",
"10": ")",
"11": "="
}
}
},
"dvorak": {
"name": "French (Dvorak)",
"keys": {
"0": {
"1": "q",
"2": ",",
"3": "i",
"4": "y",
"5": "x",
"6": "r",
"7": "l",
"8": "p",
"9": "j"
},
"1": {
"0": "o",
"1": "a",
"2": "u",
"3": "e",
"4": "b",
"5": "f",
"6": "s",
"7": "t",
"8": "n",
"9": "d",
"10": "w"
},
"2": {
"0": ":",
"3": "g",
"4": ".",
"5": "h",
"6": "v",
"7": "c",
"8": "m",
"9": "k",
"10": "z",
"11": "̈"
}
}
},
"geo": {
"name": "Georgian (France, AZERTY Tskapo)",
"include": ["ge.basic"],
"keys": {
"0": {
"6": ","
},
"3": {
"2": "%",
"3": "(",
"4": ":",
"5": ";",
"6": "?",
"8": "°",
"9": ")",
"10": "-",
"11": "<"
}
}
},
"latin9": {
"name": "French (legacy, alternative)",
"include": ["latin","nbsp.level3","level3.ralt_switch"],
"keys": {
"0": {
"0": "w",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": ",",
"7": ";",
"8": ":",
"9": "!"
},
"1": {
"0": "q",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": "m",
"10": "ù"
},
"2": {
"0": "a",
"1": "z",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "ˆ",
"11": "$"
},
"3": {
"0": "&",
"1": "é",
"2": "\"",
"3": "'",
"4": "(",
"5": "-",
"6": "è",
"7": "_",
"8": "ç",
"9": "à",
"10": ")",
"11": "="
}
}
},
"latin9_Sundeadkeys": {
"include": ["fr.latin9"],
"keys": {
"2": {
"10": "ˆ"
},
"3": {
"0": "&",
"6": "è"
}
}
},
"latin9_nodeadkeys": {
"name": "French (legacy, alternative, eliminate dead keys)",
"include": ["fr.latin9"],
"keys": {
"2": {
"10": "^"
},
"3": {
"0": "&",
"6": "è",
"11": "="
}
}
},
"latin9_sundeadkeys": {
"name": "French (legacy, alternative, Sun dead keys)",
"include": ["fr.latin9_Sundeadkeys"],
"keys": {
}
},
"mac": {
"name": "French (Macintosh)",
"include": ["level3.ralt_switch"],
"keys": {
"0": {
"0": "w",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": ",",
"7": ";",
"8": ":",
"9": "="
},
"1": {
"0": "q",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": "m",
"10": "ù"
},
"2": {
"0": "a",
"1": "z",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "ˆ",
"11": "$"
},
"3": {
"0": "&",
"1": "é",
"2": "\"",
"3": "'",
"4": "(",
"5": "§",
"6": "è",
"7": "!",
"8": "ç",
"9": "à",
"10": ")",
"11": "-"
}
}
},
"nodeadkeys": {
"name": "French (eliminate dead keys)",
"include": ["fr.basic"],
"keys": {
"0": {
"6": ",",
"9": "!"
},
"1": {
"10": "ù"
},
"2": {
"10": "^",
"11": "$"
},
"3": {
"11": "="
}
}
},
"oci": {
"name": "Occitan",
"include": ["fr.oss"],
"keys": {
"0": {
"3": "v",
"5": "n"
},
"1": {
"2": "d",
"5": "h",
"6": "j",
"7": "k",
"8": "l"
},
"2": {
"0": "a",
"1": "z",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "ˆ"
}
}
},
"olpc": {
"name": "French",
"include": ["fr.basic"],
"keys": {
"0": {
"1": "x",
"7": ";"
},
"1": {
"1": "s"
},
"2": {
"1": "z",
"10": "ˆ"
}
}
},
"oss": {
"name": "French (alternative)",
"include": ["latin","level3.ralt_switch","nbsp.level4n","keypad.oss"],
"keys": {
"0": {
"0": "w",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": ",",
"7": ";",
"8": ":",
"9": "!"
},
"1": {
"0": "q",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": "m",
"10": "ù"
},
"2": {
"0": "a",
"1": "z",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "ˆ",
"11": "$"
},
"3": {
"0": "&",
"1": "é",
"2": "\"",
"3": "'",
"4": "(",
"5": "-",
"6": "è",
"7": "_",
"8": "ç",
"9": "à",
"10": ")",
"11": "="
}
}
},
"oss_Sundeadkeys": {
"include": ["fr.oss"],
"keys": {
"1": {
"10": "ù"
},
"2": {
"10": "ˆ"
}
}
},
"oss_latin9": {
"name": "French (alternative, Latin-9 only)",
"include": ["fr.oss","keypad.oss_latin9"],
"keys": {
"0": {
"0": "w",
"1": "x",
"3": "v",
"4": "b",
"5": "n",
"6": ",",
"7": ";",
"8": ":",
"9": "!"
},
"1": {
"1": "s",
"3": "f",
"4": "g",
"8": "l"
},
"3": {
"0": "&",
"2": "\"",
"3": "'",
"4": "(",
"5": "-",
"7": "_",
"10": ")"
}
}
},
"oss_nodeadkeys": {
"name": "French (alternative, eliminate dead keys)",
"include": ["fr.oss"],
"keys": {
"1": {
"10": "ù"
},
"2": {
"10": "^"
},
"3": {
"0": "&",
"2": "\""
}
}
},
"oss_sundeadkeys": {
"name": "French (alternative, Sun dead keys)",
"include": ["fr.oss_Sundeadkeys"],
"keys": {
}
},
"sundeadkeys": {
"name": "French (Sun dead keys)",
"include": ["fr.Sundeadkeys"],
"keys": {
}
}
},
"ch": {
"basic": {
"name": "German (Switzerland)",
"include": ["latin","level3.ralt_switch"],
"keys": {
"0": {
"0": "y",
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"9": "ö",
"10": "ä"
},
"2": {
"2": "e",
"5": "z",
"8": "o",
"10": "ü",
"11": "̈"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "'",
"11": "ˆ"
}
}
},
"de": {
"include": ["ch.basic"],
"keys": {
}
},
"de_Sundeadkeys": {
"include": ["ch.basic"],
"keys": {
"2": {
"11": "̈"
},
"3": {
"10": "'",
"11": "ˆ"
}
}
},
"de_mac": {
"name": "German (Switzerland, Macintosh)",
"include": ["kpdl.comma","level3.ralt_switch"],
"keys": {
"0": {
"0": "y",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": "ö",
"10": "ä"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "z",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "ü",
"11": "̈"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "'",
"11": "ˆ"
}
}
},
"de_nodeadkeys": {
"name": "German (Switzerland, eliminate dead keys)",
"include": ["ch.basic"],
"keys": {
"2": {
"11": "¨"
},
"3": {
"10": "'",
"11": "^"
}
}
},
"de_sundeadkeys": {
"name": "German (Switzerland, Sun dead keys)",
"include": ["ch.de_Sundeadkeys"],
"keys": {
}
},
"fr": {
"name": "French (Switzerland)",
"include": ["ch.basic"],
"keys": {
}
},
"fr_Sundeadkeys": {
"include": ["ch.fr"],
"keys": {
"2": {
"11": "̈"
},
"3": {
"10": "'",
"11": "ˆ"
}
}
},
"fr_mac": {
"name": "French (Switzerland, Macintosh)",
"include": ["ch.de_mac"],
"keys": {
}
},
"fr_nodeadkeys": {
"name": "French (Switzerland, eliminate dead keys)",
"include": ["ch.fr"],
"keys": {
"2": {
"11": "¨"
},
"3": {
"10": "'",
"11": "^"
}
}
},
"fr_sundeadkeys": {
"name": "French (Switzerland, Sun dead keys)",
"include": ["ch.fr_Sundeadkeys"],
"keys": {
}
},
"legacy": {
"name": "German (Switzerland, legacy)",
"include": ["ch.basic"],
"keys": {
"3": {
"6": "7"
}
}
}
},
"nl": {
"basic": {
"name": "Dutch",
"include": ["latin","level3.ralt_switch"],
"keys": {
"0": {
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"0": "a",
"3": "f",
"9": "+",
"10": "́"
},
"2": {
"2": "e",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "̈",
"11": "*"
},
"3": {
"1": "2",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "/",
"11": "°"
}
}
},
"Sundeadkeys": {
"include": ["nl.basic"],
"keys": {
}
},
"mac": {
"name": "Dutch (Macintosh)",
"include": ["latin","level3.ralt_switch"],
"keys": {
}
},
"std": {
"name": "Dutch (standard)",
"include": ["level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": "+",
"10": "́"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "̈",
"11": "*"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "/",
"11": "°"
}
}
},
"sundeadkeys": {
"name": "Dutch (Sun dead keys)",
"include": ["nl.Sundeadkeys"],
"keys": {
}
}
},
"de": {
"basic": {
"name": "German",
"include": ["latin.type4","kpdl.comma","level3.ralt_switch"],
"keys": {
"0": {
"0": "y",
"1": "x",
"3": "v",
"4": "b",
"5": "n",
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"1": "s",
"6": "j",
"9": "ö",
"10": "ä"
},
"2": {
"2": "e",
"5": "z",
"10": "ü",
"11": "+"
},
"3": {
"1": "2",
"2": "3",
"3": "4",
"11": "́"
}
}
},
"Sundeadkeys": {
"include": ["de.basic"],
"keys": {
}
},
"T3": {
"name": "German (T3)",
"include": ["kpdl.comma","level5.modifier_mapping","level3.modifier_mapping"],
"keys": {
"0": {
"0": "y",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": "ö",
"10": "ä"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "z",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "ü",
"11": "+"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "ß",
"11": "́"
}
}
},
"adnw": {
"name": "German (Aus der Neo-Welt)",
"include": ["de.adnw_base","shift.both_capslock","level3.caps_switch","level3.bksl_switch","level5.lsgt_switch_lock","level5.ralt_switch_lock"],
"keys": {
}
},
"adnw_base": {
"include": ["de.neo_base"],
"keys": {
"0": {
"0": "x",
"1": "y",
"2": "ö",
"3": ",",
"4": "q",
"5": "b",
"6": "p",
"7": "w",
"8": "m",
"9": "z"
},
"1": {
"0": "h",
"1": "i",
"2": "e",
"3": "a",
"4": "o",
"5": "d",
"6": "t",
"7": "r",
"8": "n",
"9": "s",
"10": "ß"
},
"2": {
"0": "k",
"1": "u",
"2": "ü",
"3": ".",
"4": "ä",
"5": "v",
"6": "g",
"7": "c",
"8": "l",
"9": "j",
"10": "f"
}
}
},
"bone": {
"name": "German (Bone)",
"include": ["de.bone_base","shift.both_capslock","level3.caps_switch","level3.bksl_switch","level5.lsgt_switch_lock","level5.ralt_switch_lock"],
"keys": {
}
},
"bone_base": {
"include": ["de.neo_base"],
"keys": {
"0": {
"0": "f",
"1": "v",
"2": "ü",
"3": "ä",
"4": "ö",
"5": "y",
"6": "z",
"7": ",",
"8": ".",
"9": "k"
},
"1": {
"0": "c",
"1": "t",
"2": "i",
"3": "e",
"4": "o",
"5": "b",
"6": "n",
"7": "r",
"8": "s",
"9": "g",
"10": "q"
},
"2": {
"0": "j",
"1": "d",
"2": "u",
"3": "a",
"4": "x",
"5": "p",
"6": "h",
"7": "l",
"8": "m",
"9": "w",
"10": "ß"
}
}
},
"bone_eszett_home": {
"name": "German (Bone, eszett home row)",
"include": ["de.bone_eszett_home_base","shift.both_capslock","level3.caps_switch","level3.bksl_switch","level5.lsgt_switch_lock","level5.ralt_switch_lock"],
"keys": {
}
},
"bone_eszett_home_base": {
"include": ["de.bone_base"],
"keys": {
"1": {
"10": "ß"
},
"2": {
"10": "q"
}
}
},
"deadacute": {
"name": "German (dead acute)",
"include": ["de.deadgraveacute"],
"keys": {
"3": {
"11": "́"
}
}
},
"deadgraveacute": {
"name": "German (dead grave acute)",
"include": ["de.basic"],
"keys": {
"2": {
"11": "+"
}
}
},
"deadtilde": {
"name": "German (dead tilde)",
"include": ["de.basic"],
"keys": {
"2": {
"11": "+"
}
}
},
"dsb": {
"name": "Lower Sorbian",
"include": ["latin.basic","kpdl.comma","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"5": "n"
},
"1": {
"1": "s",
"2": "d",
"3": "f"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"8": "o"
}
}
},
"dsb_qwertz": {
"name": "Lower Sorbian (qwertz)",
"include": ["latin.basic","kpdl.comma","level3.ralt_switch"],
"keys": {
"0": {
"0": "y",
"1": "x",
"2": "c",
"3": "v",
"5": "n"
},
"1": {
"1": "s",
"2": "d",
"3": "f"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "z",
"6": "u",
"8": "o"
}
}
},
"dvorak": {
"name": "German (Dvorak)",
"include": ["us.dvorak","level3.ralt_switch"],
"keys": {
"0": {
"0": "ö",
"1": "q",
"6": "m",
"9": "#"
},
"1": {
"0": "a",
"1": "o",
"2": "e",
"3": "i",
"4": "u",
"5": "h",
"6": "d",
"7": "r",
"8": "n",
"9": "s",
"10": "l"
},
"2": {
"0": "ü",
"1": ",",
"2": ".",
"7": "c",
"8": "t",
"9": "z",
"10": "?",
"11": "/"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "+",
"11": "<"
}
}
},
"htcdream": {
"name": "German",
"include": ["inet.htcdream","level3.alt_switch"],
"keys": {
"0": {
"0": "y",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ","
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "z",
"6": "u",
"7": "i",
"8": "o",
"9": "p"
}
}
},
"hu": {
"name": "German (with Hungarian letters and no dead keys)",
"include": ["de.basic"],
"keys": {
"0": {
"0": "y"
},
"1": {
"9": "ö",
"10": "ä"
},
"2": {
"2": "e",
"5": "z",
"6": "u",
"7": "i",
"8": "o",
"10": "ü",
"11": "+"
},
"3": {
"11": "´"
}
}
},
"koy": {
"name": "German (KOY)",
"include": ["de.koy_base","shift.both_capslock","level3.caps_switch","level3.bksl_switch","level5.lsgt_switch_lock","level5.ralt_switch_lock"],
"keys": {
}
},
"koy_base": {
"include": ["de.neo_base"],
"keys": {
"0": {
"0": "x",
"1": "q",
"2": "ä",
"3": "ü",
"4": "ö",
"5": "b",
"6": "p",
"7": "w",
"8": "m",
"9": "j"
},
"1": {
"0": "h",
"1": "a",
"2": "e",
"3": "i",
"4": "u",
"5": "d",
"6": "t",
"7": "r",
"8": "n",
"9": "s",
"10": "f"
},
"2": {
"0": "k",
"1": ".",
"2": "o",
"3": ",",
"4": "y",
"5": "v",
"6": "g",
"7": "c",
"8": "l",
"9": "ß",
"10": "z"
}
}
},
"mac": {
"name": "German (Macintosh)",
"include": ["de"],
"keys": {
"0": {
"5": "n"
},
"1": {
"0": "a",
"4": "g",
"5": "h",
"8": "l",
"9": "ö"
},
"2": {
"0": "q",
"3": "r",
"6": "u",
"7": "i",
"10": "ü",
"11": "+"
},
"3": {
"0": "1",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9"
}
}
},
"mac_nodeadkeys": {
"name": "German (Macintosh, eliminate dead keys)",
"include": ["de.mac"],
"keys": {
"1": {
"9": "ö",
"10": "ä"
},
"2": {
"10": "ü",
"11": "+"
},
"3": {
"3": "4",
"11": "´"
}
}
},
"neo": {
"name": "German (Neo 2)",
"include": ["de.neo_base","shift.both_capslock","level3.caps_switch","level3.bksl_switch","level5.lsgt_switch_lock","level5.ralt_switch_lock"],
"keys": {
}
},
"neo_base": {
"keys": {
"0": {
"0": "ü",
"1": "ö",
"2": "ä",
"3": "p",
"4": "z",
"5": "b",
"6": "m",
"7": ",",
"8": ".",
"9": "j"
},
"1": {
"0": "u",
"1": "i",
"2": "a",
"3": "e",
"4": "o",
"5": "s",
"6": "n",
"7": "r",
"8": "t",
"9": "d",
"10": "y"
},
"2": {
"0": "x",
"1": "v",
"2": "l",
"3": "c",
"4": "w",
"5": "k",
"6": "h",
"7": "g",
"8": "f",
"9": "q",
"10": "ß",
"11": "́"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "̀"
}
}
},
"neo_qwerty": {
"name": "German (Neo qwerty)",
"include": ["de.neo_qwerty_base","shift.both_capslock","level3.caps_switch","level3.bksl_switch","level5.lsgt_switch_lock","level5.ralt_switch_lock"],
"keys": {
}
},
"neo_qwerty_base": {
"include": ["de.neo_qwertz_base"],
"keys": {
"0": {
"0": "z"
},
"2": {
"5": "y"
}
}
},
"neo_qwertz": {
"name": "German (Neo qwertz)",
"include": ["de.neo_qwertz_base","shift.both_capslock","level3.caps_switch","level3.bksl_switch","level5.lsgt_switch_lock","level5.ralt_switch_lock"],
"keys": {
}
},
"neo_qwertz_base": {
"include": ["de.neo_base"],
"keys": {
"0": {
"0": "y",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": "ö",
"10": "ä"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "z",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "ü"
},
"3": {
"10": "ß"
}
}
},
"nodeadkeys": {
"name": "German (eliminate dead keys)",
"include": ["de.basic"],
"keys": {
"1": {
"9": "ö",
"10": "ä"
},
"2": {
"10": "ü",
"11": "+"
},
"3": {
"11": "´"
}
}
},
"pl": {
"name": "Polish (Germany, eliminate dead keys)",
"include": ["latin.type4","de.nodeadkeys","kpdl.comma","level3.ralt_switch"],
"keys": {
"0": {
"1": "x",
"2": "c",
"5": "n"
},
"1": {
"0": "a",
"1": "s",
"3": "f"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"5": "z",
"8": "o"
},
"3": {
"3": "4"
}
}
},
"qwerty": {
"name": "German (qwerty)",
"include": ["de.basic"],
"keys": {
"0": {
"0": "z"
},
"2": {
"5": "y"
}
}
},
"ro": {
"name": "Romanian (Germany)",
"include": ["de.basic"],
"keys": {
"1": {
"0": "a",
"1": "s",
"10": "ä"
},
"2": {
"4": "t",
"7": "i"
}
}
},
"ro_nodeadkeys": {
"name": "Romanian (Germany, eliminate dead keys)",
"include": ["de.nodeadkeys"],
"keys": {
"1": {
"0": "a",
"1": "s",
"10": "ä"
},
"2": {
"4": "t",
"7": "i"
}
}
},
"ru": {
"name": "Russian (Germany, phonetic)",
"include": ["de.basic","level3.ralt_switch"],
"keys": {
"1": {
"9": "ч",
"10": "э"
},
"2": {
"10": "ш",
"11": "щ"
},
"3": {
"11": "ъ"
}
}
},
"sundeadkeys": {
"name": "German (Sun dead keys)",
"include": ["de.Sundeadkeys"],
"keys": {
}
},
"tr": {
"name": "Turkish (Germany)",
"include": ["de.basic"],
"keys": {
"0": {
"2": "c"
},
"1": {
"1": "s",
"4": "g"
},
"2": {
"7": "i"
}
}
},
"us": {
"name": "German (US keyboard with German letters)",
"include": ["us","level3.ralt_switch"],
"keys": {
"1": {
"0": "a",
"1": "s",
"9": ";",
"10": "'"
},
"2": {
"2": "e",
"6": "u",
"8": "o",
"10": "["
},
"3": {
"2": "3",
"10": "-"
}
}
}
},
"it": {
"basic": {
"name": "Italian",
"include": ["latin.type4","level3.ralt_switch"],
"keys": {
"0": {
"5": "n",
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"9": "ò",
"10": "à"
},
"2": {
"10": "è",
"11": "+"
},
"3": {
"1": "2",
"2": "3",
"3": "4",
"9": "0",
"10": "'",
"11": "ì"
}
}
},
"geo": {
"name": "Georgian (Italy)",
"include": ["it","ge.basic"],
"keys": {
"0": {
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"9": "ò",
"10": "à"
},
"2": {
"10": "è",
"11": "+"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "'",
"11": "ì"
}
}
},
"htcdream": {
"name": "Italian",
"include": ["inet.htcdream","level3.alt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ","
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p"
}
}
},
"ibm": {
"name": "Italian (IBM 142)",
"include": ["us","level3.ralt_switch","kpdl.comma"],
"keys": {
"0": {
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"9": "ò",
"10": "à"
},
"2": {
"0": "q",
"2": "e",
"10": "è",
"11": "+"
},
"3": {
"1": "2",
"2": "3",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "'",
"11": "ì"
}
}
},
"mac": {
"name": "Italian (Macintosh)",
"include": ["kpdl.dot","level3.ralt_switch"],
"keys": {
"0": {
"0": "w",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": ",",
"7": ";",
"8": ":",
"9": "ò"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": "m",
"10": "ù"
},
"2": {
"0": "q",
"1": "z",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "ì",
"11": "$"
},
"3": {
"0": "&",
"1": "\"",
"2": "'",
"3": "(",
"4": "ç",
"5": "è",
"6": ")",
"7": "£",
"8": "à",
"9": "é",
"10": "-",
"11": "="
}
}
},
"nodeadkeys": {
"name": "Italian (eliminate dead keys)",
"include": ["it.basic"],
"keys": {
"0": {
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"9": "ò",
"10": "à"
},
"3": {
"1": "2",
"2": "3",
"9": "0",
"11": "ì"
}
}
},
"olpc": {
"include": ["it.basic"],
"keys": {
"3": {
"11": "ì"
}
}
},
"us": {
"name": "Italian (US keyboard with Italian letters)",
"include": ["us.euro","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"2": "c",
"5": "n",
"7": ",",
"8": "."
},
"1": {
"0": "a",
"2": "d",
"6": "j",
"7": "k",
"8": "l",
"9": ";",
"10": "'"
},
"2": {
"2": "e",
"3": "r",
"6": "u",
"7": "i",
"8": "o"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"5": "6",
"9": "0",
"10": "-"
}
}
},
"winkeys": {
"name": "Italian (Winkeys)",
"include": ["it.basic","eurosign.5"],
"keys": {
}
}
},
"us": {
"basic": {
"name": "English (US)",
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": ";",
"10": "'"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "[",
"11": "]"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"alt-intl": {
"name": "English (US, alternative international)",
"include": ["us","level3.ralt_switch"],
"keys": {
"0": {
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"9": ";",
"10": "́"
},
"2": {
"2": "e"
},
"3": {
"4": "5",
"5": "6",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"alt-intl-unicode": {
"name": "English (US, international AltGr Unicode combining, alternative)",
"include": ["us.intl-unicode"],
"keys": {
"0": {
"8": "."
},
"3": {
"10": "-"
}
}
},
"altgr-intl": {
"name": "English (international AltGr dead keys)",
"include": ["us.intl","level3.ralt_switch"],
"keys": {
"0": {
"1": "x",
"3": "v"
},
"1": {
"6": "j",
"10": "'"
},
"2": {
"3": "r"
},
"3": {
"0": "1",
"5": "6",
"6": "7",
"7": "8"
}
}
},
"ats": {
"name": "Atsina",
"include": ["us","level3.ralt_switch","compose.rctrl"],
"keys": {
"0": {
"2": "c",
"7": ",",
"9": "/"
},
"1": {
"0": "a"
},
"2": {
"2": "e",
"6": "u",
"7": "i",
"8": "o",
"10": "[",
"11": "]"
}
}
},
"carpalx": {
"name": "English (Carpalx)",
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "j",
"5": "k",
"6": "p",
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"0": "d",
"1": "s",
"2": "t",
"3": "n",
"4": "r",
"5": "i",
"6": "a",
"7": "e",
"8": "o",
"9": "h",
"10": "'"
},
"2": {
"0": "q",
"1": "g",
"2": "m",
"3": "l",
"4": "w",
"5": "y",
"6": "f",
"7": "u",
"8": "b",
"9": ";",
"10": "[",
"11": "]"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"carpalx-altgr-intl": {
"name": "English (Carpalx, international AltGr dead keys)",
"include": ["us.carpalx-intl","level3.ralt_switch"],
"keys": {
"1": {
"10": "'"
},
"3": {
"0": "1",
"5": "6",
"6": "7",
"7": "8"
}
}
},
"carpalx-full": {
"name": "English (Carpalx, full optimization)",
"include": ["us.carpalx"],
"keys": {
"0": {
"3": "f"
},
"2": {
"5": "b",
"6": "y",
"8": "v"
}
}
},
"carpalx-full-altgr-intl": {
"name": "English (Carpalx, full optimization, international AltGr dead keys)",
"include": ["us.carpalx-altgr-intl"],
"keys": {
"0": {
"3": "f"
},
"2": {
"5": "b",
"6": "y",
"8": "v"
}
}
},
"carpalx-full-intl": {
"name": "English (Carpalx, full optimization, international with dead keys)",
"include": ["us.carpalx-intl"],
"keys": {
"0": {
"3": "f"
},
"2": {
"5": "b",
"6": "y",
"8": "v"
}
}
},
"carpalx-intl": {
"name": "English (Carpalx, international with dead keys)",
"include": ["us.carpalx","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "j",
"5": "k",
"6": "p",
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"0": "d",
"1": "s",
"2": "t",
"3": "n",
"4": "r",
"5": "i",
"6": "a",
"7": "e",
"8": "o",
"9": "h",
"10": "́"
},
"2": {
"0": "q",
"1": "g",
"2": "m",
"3": "l",
"4": "w",
"5": "y",
"6": "f",
"7": "u",
"8": "b",
"9": ";",
"10": "[",
"11": "]"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"chr": {
"name": "Cherokee",
"keys": {
"0": {
"7": ",",
"8": "."
},
"1": {
"10": "'"
},
"3": {
"0": "1",
"1": "2",
"2": "3"
}
}
},
"classmate": {
"name": "English (US)",
"include": ["us.basic","eurosign.5","level3.switch"],
"keys": {
}
},
"classmate-alt-intl": {
"name": "USA - ClassmatePC (Alternative international)",
"include": ["us.alt-intl","level3.switch"],
"keys": {
}
},
"classmate-altgr-intl": {
"name": "USA - ClassmatePC (International Fn+Alt dead-keys)",
"include": ["us.altgr-intl","level3.switch"],
"keys": {
}
},
"classmate-intl": {
"name": "USA - ClassmatePC (International)",
"include": ["us.intl","level3.switch"],
"keys": {
}
},
"colemak": {
"name": "English (Colemak)",
"include": ["us","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "k",
"6": "m",
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"0": "a",
"1": "r",
"2": "s",
"3": "t",
"4": "d",
"5": "h",
"6": "n",
"7": "e",
"8": "i",
"9": "o",
"10": "'"
},
"2": {
"0": "q",
"1": "w",
"2": "f",
"3": "p",
"4": "g",
"5": "j",
"6": "l",
"7": "u",
"8": "y",
"9": ";",
"10": "[",
"11": "]"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"crd": {
"name": "Coeur d'Alene Salish",
"include": ["us","level3.ralt_switch","compose.rctrl"],
"keys": {
"0": {
"2": "c",
"3": "v",
"8": "."
},
"1": {
"1": "s",
"6": "j"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"7": "i",
"8": "o"
},
"3": {
"5": "6",
"6": "7"
}
}
},
"cz_sk_de": {
"name": "Czech Slovak and German (US)",
"include": ["us","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"2": "c",
"5": "n"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"8": "l",
"9": ";",
"10": "'"
},
"2": {
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "["
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"dvorak": {
"name": "English (Dvorak)",
"keys": {
"0": {
"0": ";",
"1": "q",
"2": "j",
"3": "k",
"4": "x",
"5": "b",
"6": "m",
"7": "w",
"8": "v",
"9": "z"
},
"1": {
"0": "a",
"1": "o",
"2": "e",
"3": "u",
"4": "i",
"5": "d",
"6": "h",
"7": "t",
"8": "n",
"9": "s",
"10": "-"
},
"2": {
"0": "'",
"1": ",",
"2": ".",
"3": "p",
"4": "y",
"5": "f",
"6": "g",
"7": "c",
"8": "r",
"9": "l",
"10": "/",
"11": "="
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "[",
"11": "]"
}
}
},
"dvorak-alt-intl": {
"name": "English (Dvorak alternative international no dead keys)",
"include": ["us.dvorak","level3.ralt_switch"],
"keys": {
"0": {
"0": ";",
"1": "q",
"2": "j",
"3": "k",
"4": "x"
},
"1": {
"0": "a",
"1": "o",
"2": "e",
"3": "u",
"4": "i",
"9": "s"
},
"2": {
"1": ",",
"2": ".",
"3": "p",
"4": "y",
"7": "c"
},
"3": {
"3": "4"
}
}
},
"dvorak-classic": {
"name": "English (classic Dvorak)",
"keys": {
"0": {
"0": ";",
"1": "q",
"2": "j",
"3": "k",
"4": "x",
"5": "b",
"6": "m",
"7": "w",
"8": "v",
"9": "z"
},
"1": {
"0": "a",
"1": "o",
"2": "e",
"3": "u",
"4": "i",
"5": "d",
"6": "h",
"7": "t",
"8": "n",
"9": "s",
"10": "-"
},
"2": {
"0": "/",
"1": ",",
"2": ".",
"3": "p",
"4": "y",
"5": "f",
"6": "g",
"7": "c",
"8": "r",
"9": "l",
"10": "'",
"11": "="
},
"3": {
"0": "[",
"1": "7",
"2": "5",
"3": "3",
"4": "1",
"5": "9",
"6": "0",
"7": "2",
"8": "4",
"9": "6",
"10": "8",
"11": "]"
}
}
},
"dvorak-intl": {
"name": "English (Dvorak, international with dead keys)",
"include": ["us.dvorak","level3.ralt_switch"],
"keys": {
"0": {
"0": ";",
"1": "q",
"3": "k",
"6": "m",
"7": "w",
"9": "z"
},
"1": {
"0": "a",
"1": "o",
"2": "e",
"3": "u",
"4": "i",
"5": "d",
"7": "t",
"8": "n",
"9": "s"
},
"2": {
"0": "́",
"1": ",",
"2": ".",
"3": "p",
"4": "y",
"7": "c",
"8": "r",
"9": "l",
"10": "/"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "[",
"11": "]"
}
}
},
"dvorak-l": {
"name": "English (left handed Dvorak)",
"include": ["us.dvorak"],
"keys": {
"0": {
"0": "'",
"1": "x",
"2": "g",
"3": "v",
"4": "w",
"5": "n",
"6": "i",
"7": ",",
"8": "0",
"9": "9"
},
"1": {
"0": "-",
"1": "k",
"2": "c",
"3": "d",
"4": "t",
"5": "h",
"6": "e",
"7": "a",
"8": "z",
"9": "8",
"10": "7"
},
"2": {
"0": ";",
"1": "q",
"2": "b",
"3": "y",
"4": "u",
"5": "r",
"6": "s",
"7": "o",
"8": ".",
"9": "6",
"10": "5",
"11": "="
},
"3": {
"0": "[",
"1": "]",
"2": "/",
"3": "p",
"4": "f",
"5": "m",
"6": "l",
"7": "j",
"8": "4",
"9": "3",
"10": "2",
"11": "1"
}
}
},
"dvorak-r": {
"name": "English (right handed Dvorak)",
"include": ["us.dvorak"],
"keys": {
"0": {
"0": "9",
"1": "0",
"2": "x",
"3": ",",
"4": "i",
"5": "n",
"6": "w",
"7": "v",
"8": "g",
"9": "'"
},
"1": {
"0": "7",
"1": "8",
"2": "z",
"3": "a",
"4": "e",
"5": "h",
"6": "t",
"7": "d",
"8": "c",
"9": "k",
"10": "-"
},
"2": {
"0": "5",
"1": "6",
"2": "q",
"3": ".",
"4": "o",
"5": "r",
"6": "s",
"7": "u",
"8": "y",
"9": "b",
"10": ";",
"11": "="
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "j",
"5": "l",
"6": "m",
"7": "f",
"8": "p",
"9": "/",
"10": "[",
"11": "]"
}
}
},
"dvp": {
"name": "English (Programmer Dvorak)",
"include": ["us.dvorak"],
"keys": {
"0": {
"0": "'"
},
"1": {
"0": "a",
"1": "o",
"2": "e",
"3": "u",
"5": "d",
"6": "h",
"7": "t",
"8": "n",
"9": "s"
},
"2": {
"0": ";",
"1": ",",
"2": ".",
"3": "p",
"4": "y",
"7": "c",
"8": "r",
"10": "/",
"11": "@"
},
"3": {
"0": "&",
"11": "#"
}
}
},
"euro": {
"name": "English (US, with euro on 5)",
"include": ["us.basic","eurosign.5","level3.ralt_switch"],
"keys": {
}
},
"hbs": {
"name": "Serbo-Croatian (US)",
"include": ["us","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"5": "n",
"7": ",",
"8": "."
},
"1": {
"2": "d",
"8": "l",
"10": "́"
},
"2": {
"2": "e"
},
"3": {
"5": "6",
"7": "8",
"10": "-"
}
}
},
"htcdream": {
"name": "English (US)",
"include": ["inet.htcdream","level3.alt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ","
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p"
}
}
},
"ibm238l": {
"name": "English (US, IBM Arabic 238_L)",
"include": ["us.basic"],
"keys": {
"0": {
"7": ",",
"8": "."
}
}
},
"intl": {
"name": "English (US, international with dead keys)",
"include": ["us.basic","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": ";",
"10": "́"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "[",
"11": "]"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"intl-unicode": {
"name": "English (US, international AltGr Unicode combining)",
"include": ["us.intl","level3.ralt_switch"],
"keys": {
"0": {
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"9": ";",
"10": "'"
},
"3": {
"1": "2",
"2": "3",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"mac": {
"name": "English (Macintosh)",
"include": ["us.basic","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": ";",
"10": "'"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "[",
"11": "]"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"norman": {
"name": "English (Norman)",
"include": ["us.basic","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "p",
"6": "m"
},
"1": {
"0": "a",
"1": "s",
"2": "e",
"3": "t",
"4": "g",
"5": "y",
"6": "n",
"7": "i",
"8": "o",
"9": "h"
},
"2": {
"0": "q",
"1": "w",
"2": "d",
"3": "f",
"4": "k",
"5": "j",
"6": "u",
"7": "r",
"8": "l",
"9": ";"
}
}
},
"olpc": {
"name": "English (US)",
"include": ["us.basic","level3.ralt_switch"],
"keys": {
"0": {
"2": "c",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"5": "h",
"6": "j",
"9": ";",
"10": "'",
"11": "\\"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "[",
"11": "]"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"olpc2": {
"name": "English (the divide/multiply keys toggle the layout)",
"include": ["us.olpc","group.olpc"],
"keys": {
}
},
"olpcm": {
"name": "English (US)",
"include": ["us.basic","level3.ralt_switch"],
"keys": {
"0": {
"2": "c",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"5": "h",
"6": "j",
"9": ";"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "[",
"11": "]"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-"
}
}
},
"rus": {
"name": "Russian (US, phonetic)",
"include": ["us.basic","level3.ralt_switch"],
"keys": {
"1": {
"9": "ч",
"10": "ю"
},
"2": {
"10": "ш",
"11": "щ"
},
"3": {
"11": "ъ"
}
}
},
"workman": {
"name": "English (Workman)",
"include": ["us.basic","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "m",
"3": "c",
"4": "v",
"5": "k",
"6": "l"
},
"1": {
"0": "a",
"1": "s",
"2": "h",
"3": "t",
"4": "g",
"5": "y",
"6": "n",
"7": "e",
"8": "o",
"9": "i"
},
"2": {
"0": "q",
"1": "d",
"2": "r",
"3": "w",
"4": "b",
"5": "j",
"6": "f",
"7": "u",
"8": "p",
"9": ";"
}
}
},
"workman-intl": {
"name": "English (Workman, international with dead keys)",
"include": ["us.intl","level3.ralt_switch"],
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "m",
"3": "c",
"4": "v",
"5": "k",
"6": "l"
},
"1": {
"0": "a",
"1": "s",
"2": "h",
"3": "t",
"4": "g",
"5": "y",
"6": "n",
"7": "e",
"8": "o",
"9": "i"
},
"2": {
"0": "q",
"1": "d",
"2": "r",
"3": "w",
"4": "b",
"5": "j",
"6": "f",
"7": "u",
"8": "p",
"9": ";"
}
}
}
},
"latin": {
"basic": {
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": ";",
"10": "'"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "[",
"11": "]"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"intl": {
"keys": {
"0": {
"0": "z",
"1": "x",
"2": "c",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ",",
"8": ".",
"9": "/"
},
"1": {
"0": "a",
"1": "s",
"2": "d",
"3": "f",
"4": "g",
"5": "h",
"6": "j",
"7": "k",
"8": "l",
"9": ";",
"10": "'"
},
"2": {
"0": "q",
"1": "w",
"2": "e",
"3": "r",
"4": "t",
"5": "y",
"6": "u",
"7": "i",
"8": "o",
"9": "p",
"10": "[",
"11": "]"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "-",
"11": "="
}
}
},
"nodeadkeys": {
"keys": {
"0": {
"9": "/"
},
"1": {
"9": ";",
"10": "'"
},
"2": {
"10": "[",
"11": "]"
},
"3": {
"11": "="
}
}
},
"type2": {
"include": ["latin"],
"keys": {
"0": {
"2": "c",
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"0": "a"
},
"2": {
"2": "e",
"3": "r",
"4": "t",
"8": "o",
"10": "å",
"11": "̈"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0"
}
}
},
"type2_nodeadkeys": {
"include": ["latin.nodeadkeys"],
"keys": {
"0": {
"7": ",",
"8": ".",
"9": "-"
},
"2": {
"10": "å",
"11": "¨"
}
}
},
"type3": {
"include": ["latin"],
"keys": {
"0": {
"0": "y",
"3": "v",
"4": "b",
"5": "n",
"6": "m",
"7": ",",
"8": "."
},
"1": {
"3": "f",
"4": "g",
"7": "k"
},
"2": {
"0": "q",
"1": "w",
"5": "z"
}
}
},
"type3_nodeadkeys": {
"include": ["latin.nodeadkeys"],
"keys": {
}
},
"type4": {
"include": ["latin"],
"keys": {
"0": {
"7": ",",
"8": ".",
"9": "-"
},
"2": {
"2": "e"
},
"3": {
"1": "2",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0"
}
}
},
"type4_nodeadkeys": {
"include": ["latin.nodeadkeys"],
"keys": {
"0": {
"9": "-"
}
}
}
},
"es": {
"basic": {
"name": "Spanish",
"include": ["latin.type4","level3.ralt_switch"],
"keys": {
"1": {
"9": "ñ",
"10": "́"
},
"2": {
"10": "̀",
"11": "+"
},
"3": {
"0": "1",
"2": "3",
"3": "4",
"5": "6",
"10": "'",
"11": "¡"
}
}
},
"Sundeadkeys": {
"include": ["es.basic"],
"keys": {
"1": {
"10": "́"
},
"2": {
"10": "̀"
}
}
},
"ast": {
"name": "Asturian (Spain, with bottom-dot H and bottom-dot L)",
"include": ["es.basic"],
"keys": {
"1": {
"5": "h",
"8": "l"
}
}
},
"cat": {
"name": "Catalan (Spain, with middle-dot L)",
"include": ["es.basic"],
"keys": {
"1": {
"8": "l"
}
}
},
"deadtilde": {
"name": "Spanish (include dead tilde)",
"include": ["es.basic"],
"keys": {
"3": {
"3": "4"
}
}
},
"dvorak": {
"name": "Spanish (Dvorak)",
"include": ["level3.ralt_switch"],
"keys": {
"0": {
"0": "-",
"1": "q",
"2": "j",
"3": "k",
"4": "x",
"5": "b",
"6": "m",
"7": "w",
"8": "v",
"9": "z"
},
"1": {
"0": "a",
"1": "o",
"2": "e",
"3": "u",
"4": "i",
"5": "d",
"6": "r",
"7": "t",
"8": "n",
"9": "s",
"10": "́"
},
"2": {
"0": ".",
"1": ",",
"2": "ñ",
"3": "p",
"4": "y",
"5": "f",
"6": "g",
"7": "c",
"8": "h",
"9": "l",
"10": "̀",
"11": "+"
},
"3": {
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "'",
"11": "¡"
}
}
},
"mac": {
"name": "Spanish (Macintosh)",
"include": ["es"],
"keys": {
}
},
"nodeadkeys": {
"name": "Spanish (eliminate dead keys)",
"include": ["es.basic"],
"keys": {
"0": {
"9": "-"
},
"1": {
"9": "ñ",
"10": "´"
},
"2": {
"10": "`",
"11": "+"
}
}
},
"olpc": {
"name": "Spanish",
"include": ["us.basic","level3.ralt_switch"],
"keys": {
"0": {
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"9": "ñ",
"10": "+",
"11": "]"
},
"2": {
"2": "e",
"10": "́",
"11": "["
},
"3": {
"-1": "º",
"0": "1",
"1": "2",
"2": "3",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "'",
"11": "¡"
}
}
},
"olpc2": {
"name": "Spanish (OLPC2)",
"include": ["us.olpc","level3.ralt_switch"],
"keys": {
"3": {
"2": "3"
}
}
},
"olpcm": {
"name": "Spanish",
"include": ["us.basic","level3.ralt_switch"],
"keys": {
"0": {
"7": ",",
"8": ".",
"9": "-"
},
"1": {
"9": "ñ"
},
"2": {
"2": "e",
"10": "́",
"11": "+"
},
"3": {
"-1": "¿",
"0": "1",
"1": "2",
"2": "3",
"3": "4",
"4": "5",
"5": "6",
"6": "7",
"7": "8",
"8": "9",
"9": "0",
"10": "'"
}
}
},
"sundeadkeys": {
"name": "Spanish (Sun dead keys)",
"include": ["es.Sundeadkeys"],
"keys": {
}
},
"winkeys": {
"name": "Spanish (Winkeys)",
"include": ["es.basic","eurosign.5"],
"keys": {
}
}
}
}
#!/usr/bin/env python3
from __future__ import division
import os
import json
os.environ['QT_PREFERRED_BINDING'] = 'PyQt4'
from Qt import QtCore, QtGui, QtWidgets
import metawidget
#from metawidget import BaseWidget, _getCssQColorStr, _getCssQFontStr, makeQtChildProperty
try:
range = xrange
except:
pass
#fix for cx_freeze import
basePath = os.path.dirname(__file__)
if basePath.endswith('.zip'):
basePath = basePath.replace('\\library.zip', '').replace('/library.zip', '').replace('\\python27.zip', '')
with open(os.path.join(basePath, 'pianokbmap.json'), 'r') as jsf:
_localeData = json.loads(jsf.read())
_layoutCountries = {}
emptyKeys = {0: {}, 1: {}, 2: {}, 3: {}}
for _country, _mappings in _localeData.items():
for _symbolName, _layout in _mappings.items():
mapping = {'include': _layout.get('include', []), 'keys': _layout.get('keys', emptyKeys.copy()), 'symbolName': _layout.get('symbolName', _symbolName)}
name = _layout.get('name', _symbolName)
mapping['name'] = name
if _symbolName == 'basic':
try:
_layoutCountries[_country][0] = _symbolName
_layoutCountries[_country][1][_symbolName] = mapping
except:
_layoutCountries[_country] = [_symbolName, {_symbolName: mapping}]
else:
try:
_layoutCountries[_country][1][_symbolName] = mapping
except:
_layoutCountries[_country] = [_symbolName, {_symbolName: mapping}]
_layouts = {
'it': (
u'z', u's', u'x', u'd', u'c', u'v', u'g', u'b', u'h', u'n', u'j', u'm',
u',', u'l', u'.', u'\xf2', u'-', u'q', u'2', u'w', u'3', u'e', u'4', u'r',
u't', u'6', u'y', u'7', u'u', u'i', u'9', u'o', u'0', u'p', u"'", u'\xe8',
)
}
_layout1 = [
(0, 0), (1, 1), (0, 1), (1, 2), (0, 2), (0, 3), (1, 4), (0, 4), (1, 5), (0, 5), (1, 6), (0, 6)
]
_layout2 = _layout1 + [
(2, 0), (3, 1), (2, 1), (3, 2), (2, 2), (2, 3), (3, 4), (2, 4), (3, 5), (2, 5), (3, 6), (2, 6)
]
_layout3 = _layout1 + [
(0, 7), (1, 8), (0, 8), (1, 9), (0, 9), (2, 0), (3, 1), (2, 1), (3, 2), (2, 2), (3, 3), (2, 3),
(2, 4), (3, 5), (2, 5), (3, 6), (2, 6), (2, 7), (3, 8), (2, 8), (3, 9), (2, 9), (3, 10), (2, 10),
]
_noteNames = ['c', 'c#', 'd', 'd#', 'e', 'f', 'f#', 'g', 'g#', 'a', 'a#', 'b']
_noteAliases = {
'c': ('b#', -1),
'c#': ('db', 0),
'd#': ('eb', 0),
'e': ('fb', 0),
'f': ('e#', 0),
'f#': ('gb', 0),
'g#': ('ab', 0),
'a#': ('bb', 0),
'b': ('cb', 1),
}
_whiteKeys = (0, 2, 4, 5, 7, 9, 11)
_noteNumberToName = {}
_noteNameToNumber = {}
sanitize = lambda m, v, M: max(m, min(v, M))
for _noteId in range(128):
_octave, _note = divmod(_noteId, 12)
_noteName = _noteNames[_note]
_fullNoteName = '{}{}'.format(_noteName, -2 + _octave)
_noteNumberToName[_noteId] = _fullNoteName
_noteNameToNumber[_fullNoteName] = _noteId
try:
_alias, _offset = _noteAliases[_noteName]
_noteNameToNumber['{}{}'.format(_alias, -2 + _octave + _offset)] = _noteId
except:
pass
def _isWhiteKey(noteId):
return noteId % 12 in _whiteKeys
noteFreqs = {}
def noteFrequency(note, tuning=440):
try:
return noteFreqs[tuning][note]
except:
f = '{:.03f}'.format(2 ** ((note - 69) / 12.) * tuning).rstrip('0').rstrip('.')
try:
noteFreqs[tuning][note] = f
except:
noteFreqs[tuning] = {}
noteFreqs[tuning][note] = f
return f
class MetaKey(QtWidgets.QGraphicsItem):
x = 0
width = 18
height = 100
pressed = 0
keyBrush = QtCore.Qt.white
def __init__(self, note, showFrequency=False, tuning=440):
QtWidgets.QGraphicsItem.__init__(self, parent=None)
self.note = note
self.noteName = _noteNumberToName[note]
self._shortcut = ''
self.shortcutPaintFunc = lambda *args: None
self.showFrequency(showFrequency, tuning)
@property
def shortcut(self):
return self._shortcut
@shortcut.setter
def shortcut(self, shortcut):
self._shortcut = shortcut
self.shortcutPaintFunc = self.shortcutPaint if shortcut else lambda *args: None
def showFrequency(self, showFrequency=False, tuning=440):
if showFrequency:
self.setToolTip('{} ({}Hz)'.format(self.noteName.upper(), noteFrequency(self.note, tuning)))
else:
self.setToolTip(self.noteName.upper())
def emitNoteEvent(self, velocity, state):
# if velocity < 0:
# velocity = 0
# elif velocity > 127:
# velocity = 127
self.scene().noteEvent.emit(state, self.note, sanitize(0, velocity, 127))
def mousePressEvent(self, event):
self.emitNoteEvent(int(round(event.pos().y() * 127 / self.height, 0)), True)
self.pressed = 1
self.update()
def mouseReleaseEvent(self, event):
self.emitNoteEvent(int(round(event.pos().y() * 127 / self.height, 0)), False)
self.pressed = 0
try:
self.ungrabMouse()
except:
pass
self.update()
def mouseMoveEvent(self, event):
item = self.scene().itemAt(self.mapToScene(event.pos()), QtGui.QTransform())
if item == self:
if not self.pressed:
self.mousePressEvent(event)
elif item is None:
if self.pressed:
self.mouseReleaseEvent(event)
self.grabMouse()
else:
self.mouseReleaseEvent(event)
if isinstance(item, QtWidgets.QGraphicsItem):
item.mousePressEvent(event)
item.grabMouse()
def boundingRect(self):
return QtCore.QRectF(0, 0, self.x + self.width, self.height)
class WhiteKey(MetaKey):
pressedShadow = QtGui.QPolygon([
QtCore.QPoint(.5, 2),
QtCore.QPoint(.5, 98),
QtCore.QPoint(5, 98),
QtCore.QPoint(1.5, 2),
])
pressedShadowGradient = QtGui.QLinearGradient(0, 0, 1, 0)
pressedShadowGradient.setCoordinateMode(pressedShadowGradient.ObjectBoundingMode)
pressedShadowGradient.setColorAt(0, QtGui.QColor(64, 64, 64, 192))
pressedShadowGradient.setColorAt(.8, QtGui.QColor(192, 192, 192, 192))
pressedShadowGradient.setColorAt(1, QtGui.QColor(255, 255, 255, 192))
pressedShadowPen = QtGui.QPen(QtGui.QColor(192, 192, 192, 128), 4)
# pressedShadowBrush = QtGui.QColor(192, 192, 192, 192)
pressedShadowBrush = pressedShadowGradient
def __init__(self, *args, **kwargs):
MetaKey.__init__(self, *args, **kwargs)
self.pressedPaintFunction = lambda qp: None
if not self.note % 12:
self.paintCFunc = lambda qp: self.paintC(qp, 'C{}'.format(self.note // 12 - 2))
else:
self.paintCFunc = lambda *args: None
self._prevBlack = None
self.prevWhite = None
# self.prevBlackShadow = lambda: None
@property
def prevBlack(self):
return self._prevBlack
@prevBlack.setter
def prevBlack(self, key):
self._prevBlack = key
# self.prevBlackShadow = key.update
def mousePressEvent(self, event):
self.pressedPaintFunction = self.pressedPaint
if self._prevBlack:
self.prevBlack.setWhiteShadow(True)
MetaKey.mousePressEvent(self, event)
def mouseReleaseEvent(self, event):
self.pressedPaintFunction = lambda qp: None
if self._prevBlack:
self.prevBlack.setWhiteShadow(False)
MetaKey.mouseReleaseEvent(self, event)
def triggerNoteEvent(self, eventType, velocity):
if eventType and velocity == 0:
eventType = False
if eventType:
self.pressedPaintFunction = self.pressedPaint
if self._prevBlack:
self.prevBlack.setWhiteShadow(True)
self.pressed = 1
self.emitNoteEvent(velocity, True)
self.update()
else:
self.pressedPaintFunction = lambda qp: None
self.pressed = 0
if self._prevBlack:
self.prevBlack.setWhiteShadow(False)
self.emitNoteEvent(velocity, False)
self.update()
if self.scene().mouseGrabberItem() == self:
self.ungrabMouse()
def paint(self, qp, *args, **kwargs):
qp.translate(.5, .5)
qp.setRenderHints(QtGui.QPainter.Antialiasing)
qp.setPen(QtCore.Qt.darkGray)
qp.setBrush(self.keyBrush)
qp.drawRoundedRect(self.x, 0, self.width, self.height - 1.1 + self.pressed, 1, 1)
self.pressedPaintFunction(qp)
self.paintCFunc(qp)
self.shortcutPaintFunc(qp)
def shortcutPaint(self, qp):
qp.setPen(QtCore.Qt.black)
xScale = 1 / qp.transform().m11()
yScale = 1 / qp.transform().m22()
qp.save()
font = qp.font()
pointSize = max(.1, (font.pointSizeF() / max(xScale, yScale)) - 1)
font.setPointSizeF(pointSize)
font.setBold(True)
qp.setFont(font)
qp.scale(xScale, yScale)
qp.drawText(self.x, 0, self.width / xScale, (self.height - 1) / yScale - 20 / yScale, QtCore.Qt.AlignHCenter|QtCore.Qt.AlignBottom, self.shortcut)
qp.restore()
def pressedPaint(self, qp):
if not self.prevWhite or self.prevWhite.pressed:
return
qp.setPen(self.pressedShadowPen)
qp.setBrush(self.pressedShadowBrush)
qp.drawPolygon(self.pressedShadow)
def paintC(self, qp, label):
qp.setPen(QtCore.Qt.darkGray)
xScale = 1 / qp.transform().m11()
yScale = 1 / qp.transform().m22()
qp.save()
font = qp.font()
pointSize = max(.1, (font.pointSizeF() / max(xScale, yScale)) - 1)
font.setPointSize(pointSize)
qp.setFont(font)
qp.scale(xScale, yScale)
qp.drawText(self.x, self.y(), self.width / xScale, (self.height - 1) / yScale - 1 / yScale, QtCore.Qt.AlignHCenter|QtCore.Qt.AlignBottom, label)
qp.restore()
class BlackKey(MetaKey):
height = int(MetaKey.height * .6)
bottomHeight = 8
topHeight = height - bottomHeight
width = int(MetaKey.width * .75)
keyBodyNormal = QtGui.QLinearGradient(0, 0, 0, 1)
keyBodyNormal.setCoordinateMode(keyBodyNormal.ObjectBoundingMode)
keyBodyNormal.setColorAt(0, QtGui.QColor(24, 24, 24))
keyBodyNormal.setColorAt(.4, QtGui.QColor(48, 40, 40))
keyBodyNormal.setColorAt(.5, QtGui.QColor(48, 40, 40))
keyBodyNormal.setColorAt(1, QtGui.QColor(24, 24, 24))
keyBodyPressed = QtGui.QLinearGradient(0, 0, 0, 1)
keyBodyPressed.setCoordinateMode(keyBodyPressed.ObjectBoundingMode)
keyBodyPressed.setColorAt(0, QtGui.QColor(48, 48, 48))
keyBodyPressed.setColorAt(.4, QtGui.QColor(72, 64, 64))
keyBodyPressed.setColorAt(.5, QtGui.QColor(72, 64, 64))
keyBodyPressed.setColorAt(1, QtGui.QColor(48, 48, 48))
leftBorder = QtGui.QPolygon([
QtCore.QPoint(.5, .5),
QtCore.QPoint(.5, height),
QtCore.QPoint(1, height),
QtCore.QPoint(1, .5),
])
rightBorderLeft = width - 1
rightBorderRight = width - .5
rightBorder = QtGui.QPolygon([
QtCore.QPoint(rightBorderLeft, .5),
QtCore.QPoint(rightBorderLeft, height),
QtCore.QPoint(rightBorderRight, height),
QtCore.QPoint(rightBorderRight, .5),
])
shadowPen = QtGui.QColor(200, 200, 200, 160)
shadowWhiteNormalBrush = QtGui.QLinearGradient(0, 0, 0, 1)
shadowWhiteNormalBrush.setCoordinateMode(shadowWhiteNormalBrush.ObjectBoundingMode)
shadowWhiteNormalBrush.setColorAt(0, QtGui.QColor(48, 48, 48, 92))
shadowWhiteNormalBrush.setColorAt(.2, QtGui.QColor(64, 64, 64, 128))
shadowWhiteNormalBrush.setColorAt(1, QtGui.QColor(128, 128, 128, 128))
shadowWhitePressedBrush = QtGui.QLinearGradient(0, 0, 0, 1)
shadowWhitePressedBrush.setCoordinateMode(shadowWhitePressedBrush.ObjectBoundingMode)
shadowWhitePressedBrush.setColorAt(0, QtGui.QColor(32, 32, 32, 92))
shadowWhitePressedBrush.setColorAt(.2, QtGui.QColor(32, 32, 32, 128))
shadowWhitePressedBrush.setColorAt(1, QtGui.QColor(96, 96, 96, 128))
shadowBrushes = shadowWhiteNormalBrush, shadowWhitePressedBrush
shadowBrush = shadowWhiteNormalBrush
@classmethod
def setRatio(cls, ratio):
cls.height = int(MetaKey.height * ratio)
cls.topHeight = cls.height - cls.bottomHeight
def __init__(self, *args, **kwargs):
MetaKey.__init__(self, *args, **kwargs)
self.keyBody = self.keyBodyNormal
self.shadowPaint = self.normalWhiteNormalShadowPaint
self.bottomPaint = self.normalBottomPaint
def setWhiteShadow(self, state):
self.shadowBrush = self.shadowBrushes[state]
self.shadowPaint = self.normalWhitePressedShadowPaint if state else self.normalWhiteNormalShadowPaint
def mousePressEvent(self, event):
self.keyBody = self.keyBodyPressed
self.shadowPaint = self.pressedShadowPaint
self.bottomPaint = self.pressedBottomPaint
self.nextWhite.update()
MetaKey.mousePressEvent(self, event)
def mouseReleaseEvent(self, event):
self.keyBody = self.keyBodyNormal
self.shadowPaint = self.normalWhiteNormalShadowPaint
self.bottomPaint = self.normalBottomPaint
self.nextWhite.update()
MetaKey.mouseReleaseEvent(self, event)
def triggerNoteEvent(self, eventType, velocity):
if eventType and velocity == 0:
eventType = False
if eventType:
self.keyBody = self.keyBodyPressed
self.shadowPaint = self.pressedShadowPaint
self.bottomPaint = self.pressedBottomPaint
self.pressed = 1
self.emitNoteEvent(velocity, True)
self.update()
else:
self.keyBody = self.keyBodyNormal
self.shadowPaint = self.normalWhiteNormalShadowPaint
self.bottomPaint = self.normalBottomPaint
self.pressed = 0
self.emitNoteEvent(velocity, False)
self.update()
if self.scene().mouseGrabberItem() == self:
self.ungrabMouse()
self.nextWhite.update()
def paint(self, qp, *args, **kwargs):
qp.translate(.5, .5)
qp.setRenderHints(QtGui.QPainter.Antialiasing)
qp.setPen(self.shadowPen)
qp.setBrush(self.shadowBrush)
self.shadowPaint(qp)
qp.setPen(QtCore.Qt.NoPen)
qp.setBrush(self.keyBody)
qp.drawRoundedRect(self.x, 0, self.width, self.height, 1, 1)
qp.setBrush(QtCore.Qt.darkGray)
qp.drawPolygon(self.leftBorder)
qp.setPen(QtCore.Qt.black)
qp.drawPolygon(self.rightBorder)
self.bottomPaint(qp)
self.shortcutPaintFunc(qp)
def shortcutPaint(self, qp):
qp.setPen(QtCore.Qt.white)
xScale = 1 / qp.transform().m11()
yScale = 1 / qp.transform().m22()
qp.save()
font = qp.font()
font.setPointSize(int(font.pointSize() / max(xScale, yScale)) - 1)
font.setBold(True)
qp.setFont(font)
qp.scale(xScale, yScale)
qp.drawText(self.x, 0, self.width / xScale, (self.height - 1) / yScale - 20 / yScale, QtCore.Qt.AlignHCenter|QtCore.Qt.AlignBottom, self.shortcut)
qp.restore()
def normalWhiteNormalShadowPaint(self, qp):
qp.drawRoundedRect(self.x + 1, 0, self.width + 2, self.height + 1, 2, 2)
def normalWhitePressedShadowPaint(self, qp):
qp.save()
qp.translate(.5, .2)
qp.drawRoundedRect(self.x + 1, 0, self.width + 2, self.height + 1, 2, 2)
qp.restore()
def pressedShadowPaint(self, qp):
qp.drawRoundedRect(self.x + 1, 0, self.width + 1, self.height + 1, 2, 2)
def pressedBottomPaint(self, qp):
qp.setPen(QtCore.Qt.NoPen)
qp.setBrush(QtCore.Qt.black)
qp.drawRoundedRect(self.x + 1, self.topHeight + 2, self.width - 2, self.bottomHeight - 2, 1, 1)
def normalBottomPaint(self, qp):
qp.setPen(QtCore.Qt.NoPen)
qp.setBrush(QtCore.Qt.black)
qp.drawRoundedRect(self.x + 1, self.topHeight, self.width - 2, self.bottomHeight, 1, 1)
class TopShadow(QtWidgets.QGraphicsItem):
width = 1
height = 10
gradient = QtGui.QLinearGradient(0, 0, 0, 1)
gradient.setCoordinateMode(gradient.ObjectBoundingMode)
gradient.setColorAt(0, QtGui.QColor(92, 92, 92, 192))
gradient.setColorAt(1, QtGui.QColor(255, 255, 255, 0))
def __init__(self, *args, **kwargs):
QtWidgets.QGraphicsItem.__init__(self, *args, **kwargs)
self.setAcceptedMouseButtons(QtCore.Qt.NoButton)
def boundingRect(self):
return QtCore.QRectF(0, 0, self.width, self.height)
def paint(self, qp, *args, **kwargs):
qp.translate(.5, .5)
qp.setPen(QtCore.Qt.NoPen)
qp.setBrush(self.gradient)
qp.drawRect(self.boundingRect())
class PianoScene(QtWidgets.QGraphicsScene):
noteEvent = QtCore.pyqtSignal(bool, int, int)
class PianoKeyboard(QtWidgets.QGraphicsView):
noteEvent = QtCore.pyqtSignal(bool, int, int)
def __init__(self, parent=None):
QtWidgets.QGraphicsView.__init__(self, parent)
self.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
palette = self.palette()
palette.setColor(palette.Base, QtGui.QColor(QtCore.Qt.transparent))
self.setPalette(palette)
sizePolicy = self.sizePolicy()
sizePolicy.setHeightForWidth(True)
self.setSizePolicy(sizePolicy)
self.pianoScene = PianoScene(self)
self.pianoScene.noteEvent.connect(self.noteEvent)
self.setScene(self.pianoScene)
self.setFrameStyle(0)
self._aspectRatio = QtCore.Qt.KeepAspectRatio
self._blackKeyRatio = int(BlackKey.height / WhiteKey.height * 100)
self._firstNote = 36
self._lastNote = 96
self._octaves = 5
self._noteOffset = 1
self._showShortcuts = True
self._defaultVelocity = 127
self._polyphonic = True
self._showFrequency = False
self._tuning = 440
self.polyNote = None
self.setKeyboard()
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
# self.aspectRatio = QtCore.Qt.KeepAspectRatioByExpanding
def heightForWidth(self, width):
keyWidth = width / self._whiteKeysWidth
# print(width, self._whiteKeysWidth, keyWidth, keyWidth * 5.55555555)
return int(keyWidth * 5.55555555)
# return QtWidgets.QGraphicsView.heightForWidth(self, width)
def sizeHint(self):
return QtCore.QSize(self.width(), self.heightForWidth(self.width()))
# @QtCore.pyqtProperty(int)
# def keyWidth(self):
# return MetaKey.width
#
# @keyWidth.setter
# def keyWidth(self, width):
# if width < 10:
# width = 10
# elif width > 50:
# width = 50
# MetaKey.width = width
# self.update()
@QtCore.pyqtProperty(QtCore.Qt.AspectRatioMode, doc='aoaoa')
def aspectRatio(self):
return self._aspectRatio
@aspectRatio.setter
def aspectRatio(self, aspectRatio):
sizePolicy = self.sizePolicy()
if aspectRatio == QtCore.Qt.KeepAspectRatioByExpanding:
aspectRatio = QtCore.Qt.KeepAspectRatio
sizePolicy.setHeightForWidth(True)
elif aspectRatio == QtCore.Qt.KeepAspectRatio:
sizePolicy.setHeightForWidth(True)
else:
sizePolicy.setHeightForWidth(False)
self.setSizePolicy(sizePolicy)
self._aspectRatio = aspectRatio
QtWidgets.QApplication.postEvent(self, QtCore.QEvent(QtCore.QEvent.UpdateRequest))
self.fitInView(1, 1, self._whiteKeysWidth * MetaKey.width - 1, 99, QtCore.Qt.IgnoreAspectRatio)
@QtCore.pyqtProperty(int)
def blackKeyRatio(self):
return self._blackKeyRatio
@blackKeyRatio.setter
def blackKeyRatio(self, ratio):
# if ratio < 30:
# ratio = 30
# elif ratio > 100:
# ratio = 100
self._blackKeyRatio = sanitize(30, ratio, 100)
BlackKey.setRatio(self._blackKeyRatio / 100)
# BlackKey.height = WhiteKey.height * ratio
self.updateScene(self.pianoScene.sceneRect())
@QtCore.pyqtProperty(int)
def firstNote(self):
return self._firstNote
@firstNote.setter
def firstNote(self, firstNote):
if not _isWhiteKey(firstNote):
firstNote -= 1
# if firstNote < 0:
# firstNote = 0
# elif firstNote > 127:
# firstNote = 127
firstNote = sanitize(0, firstNote, 127)
#TODO: check consistency!
while firstNote + self._octaves * 12 + self._noteOffset > 127:
if self._octaves > 0:
self._octaves -= 1
else:
firstNote -= 1
self._firstNote = firstNote
self.noteOffset = self.noteOffset
lastNote = firstNote + self._octaves * 12 + self._noteOffset
if not _isWhiteKey(lastNote):
self._noteOffset += -1 if not self._noteOffset <= 10 else 1
self._lastNote = firstNote + self._octaves * 12 + self._noteOffset
self.setKeyboard()
@QtCore.pyqtProperty(int)
def octaves(self):
return self._octaves
@octaves.setter
def octaves(self, octaves):
# if octaves < 0:
# octaves = 0
# elif octaves > 10:
# octaves = 10
octaves = sanitize(0, octaves, 10)
lastNote = self._firstNote + octaves * 12 + self._noteOffset
noteOffset = self._noteOffset
while lastNote > 127:
noteOffset = self._noteOffset - 1
lastNote = self._firstNote + octaves * 12 + noteOffset
if not _isWhiteKey(lastNote):
noteOffset -= 1
self._octaves = octaves
self._noteOffset = noteOffset
self._lastNote = self._firstNote + self._octaves * 12 + self._noteOffset
self.setKeyboard()
@QtCore.pyqtProperty(int)
def noteOffset(self):
return self._noteOffset
@noteOffset.setter
def noteOffset(self, noteOffset):
# if noteOffset > 11:
# noteOffset = 11
# elif noteOffset < -10:
# noteOffset = -10
noteOffset = sanitize(-10, noteOffset, 11)
lastNote = self._firstNote + self._octaves * 12 - 1 + noteOffset
if not _isWhiteKey(lastNote):
#TODO: valuta un baseOffset?
noteOffset += 1
self._noteOffset = noteOffset
self._lastNote = self._firstNote + self._octaves * 12 - 1 + noteOffset
self.setKeyboard()
@QtCore.pyqtProperty(bool)
def showShortcuts(self):
return self._showShortcuts
@showShortcuts.setter
def showShortcuts(self, show):
self._showShortcuts = show
self.setShortcuts()
@QtCore.pyqtProperty(int)
def defaultVelocity(self):
return self._defaultVelocity
@defaultVelocity.setter
def defaultVelocity(self, velocity):
# if velocity < 0:
# velocity = 0
# elif velocity > 127:
# velocity = 127
self._defaultVelocity = sanitize(0, velocity, 127)
@QtCore.pyqtProperty(bool)
def polyphonic(self):
return self._polyphonic
@polyphonic.setter
def polyphonic(self, state):
self._polyphonic = state
if not state:
self.pianoScene.noteEvent.disconnect(self.noteEvent)
self.pianoScene.noteEvent.connect(self.checkPolyphony)
else:
self.pianoScene.noteEvent.disconnect(self.checkPolyphony)
self.pianoScene.noteEvent.connect(self.noteEvent)
@QtCore.pyqtProperty(bool)
def showFrequency(self):
return self._showFrequency
@showFrequency.setter
def showFrequency(self, show):
self._showFrequency = show
for key in self.keys.values():
key.showFrequency(show, self._tuning)
@QtCore.pyqtProperty(int)
def tuning(self):
return self._tuning
@tuning.setter
def tuning(self, tuning):
self._tuning = max(410, min(tuning, 460))
for key in self.keys.values():
key.showFrequency(self._showFrequency, self._tuning)
def checkPolyphony(self, eventType, note, velocity):
#velocity == 0 is note off!
if not eventType or not velocity:
self.noteEvent.emit(eventType, note, velocity)
self.polyNote = None
elif self.polyNote is not None:
if self.polyNote != note:
self.noteEvent.emit(False, self.polyNote, 0)
self.noteEvent.emit(True, note, velocity)
self.polyNote = note
else:
self.noteEvent.emit(eventType, note, velocity)
self.polyNote = note
def setKeyboard(self):
self.keys = {}
self.shortcuts = {}
self.pianoScene.clear()
whiteKeysWidth = 0
self._keyRange = range(self._firstNote, self._lastNote + 1)
for k in self._keyRange:
if _isWhiteKey(k):
key = WhiteKey(k, self._showFrequency, self._tuning)
self.pianoScene.addItem(key)
key.setPos(whiteKeysWidth * MetaKey.width, 0)
whiteKeysWidth += 1
try:
if not _isWhiteKey(k - 1):
prevBlack = self.keys[k - 1]
prevBlack.nextWhite = key
key.prevBlack = prevBlack
prevWhite = self.keys[k - 2]
key.prevWhite = prevWhite
elif k > 0:
prevWhite = self.keys[k - 1]
key.prevWhite = prevWhite
except:
pass
else:
keyDelta = k % 12
shift = 0
if keyDelta in (1, 6):
shift = -2
elif keyDelta in (3, 10):
shift = +2
key = BlackKey(k, self._showFrequency, self._tuning)
self.pianoScene.addItem(key)
key.setZValue(2)
key.setPos(whiteKeysWidth * MetaKey.width - BlackKey.width * .5 + shift, 0)
self.keys[k] = key
topShadow = TopShadow()
topShadow.width = whiteKeysWidth * MetaKey.width
self.pianoScene.addItem(topShadow)
self._whiteKeysWidth = whiteKeysWidth
self.setShortcuts()
self.resizeEvent()
def getMapping(self, country, symbolName=None):
countryLayout = _layoutCountries.get(country, _layoutCountries['latin'])
if symbolName is None or symbolName == country:
symbolName = countryLayout[0]
layouts = countryLayout[1]
base = {0: {}, 1: {}, 2: {}, 3: {}}
try:
layout = layouts[symbolName]
base['name'] = layouts[symbolName]['name']
except Exception as e:
layout = layouts['basic']
# print(e, country, symbolName)
# print(layoutCountries[country])
for include in layout.get('include', []):
includeSplit = include.split('.')
includeCountry = includeSplit[0]
try:
includeLayout = includeSplit[1]
except:
includeLayout = 'basic'
try:
includeMap = self.getMapping(includeCountry, includeLayout)
for row in range(4):
base[row].update({int(k):v for k, v in includeMap[row].items()})
except:
continue
for row in range(4):
try:
base[row].update({int(k):v for k, v in layout['keys'][str(row)].items()})
except:
pass
return base
def setShortcuts(self):
if self._showShortcuts:
lang, country = QtCore.QLocale().name().split('_')
country = country.lower()
keyboardMapping = self.getMapping(country, lang)
note = self._firstNote
if self._octaves > 4:
note += (self._octaves - 3) * 6
while note % 12:
note += 1
#determine the first C and actual octave extension
extension = self._lastNote - note + 1
if extension >= 36:
layout = _layout3
elif extension >= 24:
layout = _layout2
else:
layout = _layout1
pianoMapping = [keyboardMapping[k[0]][k[1]] for k in layout]
for shortcut in pianoMapping:
try:
key = self.keys[note]
key.shortcut = shortcut.upper()
self.shortcuts[shortcut] = key
note += 1
except:
break
else:
for key in self.keys.values():
key.shortcut = ''
self.pianoScene.update(self.pianoScene.sceneRect())
def setAllKeysUp(self):
for key in self.keys.values():
if key.pressed:
key.triggerNoteEvent(False, 127)
self.pianoScene.update()
@QtCore.pyqtSlot(bool, int)
@QtCore.pyqtSlot(bool, int, int)
def triggerNoteEvent(self, eventType, note, velocity=None):
self.keys[note].triggerNoteEvent(eventType, velocity if velocity is not None else self._defaultVelocity)
def resizeEvent(self, event=None):
sceneRect = QtCore.QRectF(0, 0, self._whiteKeysWidth * MetaKey.width, 100)
self.pianoScene.setSceneRect(sceneRect)
self.fitInView(sceneRect.adjusted(1, 1, -1, -1), QtCore.Qt.IgnoreAspectRatio)
def keyPressEvent(self, event):
if event.isAutoRepeat():
return
try:
self.shortcuts[event.text()].triggerNoteEvent(True, self._defaultVelocity)
except:
pass
def keyReleaseEvent(self, event):
if event.isAutoRepeat():
return
try:
self.shortcuts[event.text()].triggerNoteEvent(False, 0)
except:
pass
def focusOutEvent(self, event):
self.setAllKeysUp()
QtWidgets.QGraphicsView.focusOutEvent(self, event)
def printEvent(eventType, note, velocity):
print('Note{eventType} {note} {noteName} {velocity}'.format(
eventType = 'On' if eventType else 'Off',
note = note,
noteName = _noteNumberToName[note],
velocity = velocity
))
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
piano = PianoKeyboard()
piano.noteEvent.connect(printEvent)
piano.showFrequency = True
piano.tuning = 440
# piano.aspectRatio = QtCore.Qt.KeepAspectRatio
piano.show()
sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment