mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-05 16:35:33 +00:00
164 lines
5.5 KiB
TypeScript
164 lines
5.5 KiB
TypeScript
/// <reference path="oskKey.ts" />
|
|
|
|
namespace com.keyman.osk {
|
|
let Codes = com.keyman.text.Codes;
|
|
|
|
export class OSKBaseKey extends OSKKey {
|
|
private capLabel: HTMLDivElement;
|
|
public readonly row: OSKRow;
|
|
|
|
constructor(spec: OSKKeySpec, layer: string, row: OSKRow) {
|
|
super(spec, layer);
|
|
this.row = row;
|
|
}
|
|
|
|
getId(): string {
|
|
// Define each key element id by layer id and key id (duplicate possible for SHIFT - does it matter?)
|
|
return this.spec.elementID;
|
|
}
|
|
|
|
getCoreId(): string {
|
|
return this.spec.coreID;
|
|
}
|
|
|
|
getBaseId(): string {
|
|
return this.spec.baseKeyID;
|
|
}
|
|
|
|
// Produces a small reference label for the corresponding physical key on a US keyboard.
|
|
private generateKeyCapLabel(): HTMLDivElement {
|
|
// Create the default key cap labels (letter keys, etc.)
|
|
var x = Codes.keyCodes[this.spec.baseKeyID];
|
|
switch(x) {
|
|
// Converts the keyman key id code for common symbol keys into its representative ASCII code.
|
|
// K_COLON -> K_BKQUOTE
|
|
case 186: x=59; break;
|
|
case 187: x=61; break;
|
|
case 188: x=44; break;
|
|
case 189: x=45; break;
|
|
case 190: x=46; break;
|
|
case 191: x=47; break;
|
|
case 192: x=96; break;
|
|
// K_LBRKT -> K_QUOTE
|
|
case 219: x=91; break;
|
|
case 220: x=92; break;
|
|
case 221: x=93; break;
|
|
case 222: x=39; break;
|
|
default:
|
|
// No other symbol character represents a base key on the standard QWERTY English layout.
|
|
if(x < 48 || x > 90) {
|
|
x=0;
|
|
}
|
|
}
|
|
|
|
let q = document.createElement('div');
|
|
q.className='kmw-key-label';
|
|
if(x > 0) {
|
|
q.innerText=String.fromCharCode(x);
|
|
} else {
|
|
// Keyman-only virtual keys have no corresponding physical key.
|
|
// So, no text for the key-cap.
|
|
}
|
|
return q;
|
|
}
|
|
|
|
private processSubkeys(btn: KeyElement, vkbd: VisualKeyboard) {
|
|
// Add reference to subkey array if defined
|
|
var bsn: number, bsk=btn['subKeys'] = this.spec['sk'];
|
|
// Transform any special keys into their PUA representations.
|
|
for(bsn=0; bsn<bsk.length; bsn++) {
|
|
if(bsk[bsn]['sp'] == '1' || bsk[bsn]['sp'] == '2') {
|
|
var oldText=bsk[bsn]['text'];
|
|
bsk[bsn]['text']=this.renameSpecialKey(oldText, vkbd);
|
|
}
|
|
|
|
// If a subkey doesn't have a defined layer property, copy it from the base key's layer by default.
|
|
if(!bsk[bsn].layer) {
|
|
bsk[bsn].layer = btn.key.layer
|
|
}
|
|
}
|
|
|
|
// If a subkey array is defined, add an icon
|
|
var skIcon = document.createElement('div');
|
|
skIcon.className='kmw-key-popup-icon';
|
|
//kDiv.appendChild(skIcon);
|
|
btn.appendChild(skIcon);
|
|
}
|
|
|
|
construct(vkbd: VisualKeyboard): HTMLDivElement {
|
|
let spec = this.spec;
|
|
|
|
let kDiv = document.createElement('div');
|
|
kDiv.className='kmw-key-square';
|
|
|
|
let btnEle = document.createElement('div');
|
|
let btn = this.btn = link(btnEle, new KeyData(this, spec['id']));
|
|
|
|
// Set button class
|
|
this.setButtonClass();
|
|
|
|
// Add the (US English) keycap label for layouts requesting display of underlying keys
|
|
let keyCap = this.capLabel = this.generateKeyCapLabel();
|
|
btn.appendChild(keyCap);
|
|
|
|
// Define each key element id by layer id and key id (duplicate possible for SHIFT - does it matter?)
|
|
btn.id=this.getId();
|
|
|
|
// Make sure the key text is the element's first child - processSubkeys()
|
|
// will add an extra element if subkeys exist, which can interfere with
|
|
// keyboard/language name display on the space bar!
|
|
btn.appendChild(this.label = this.generateKeyText(vkbd));
|
|
|
|
// Handle subkey-related tasks.
|
|
if(typeof(spec['sk']) != 'undefined' && spec['sk'] != null) {
|
|
this.processSubkeys(btn, vkbd);
|
|
} else {
|
|
btn['subKeys']=null;
|
|
}
|
|
|
|
// Add text to button and button to placeholder div
|
|
kDiv.appendChild(btn);
|
|
|
|
// The 'return value' of this process.
|
|
return this.square = kDiv;
|
|
}
|
|
|
|
public refreshLayout(vkbd: VisualKeyboard) {
|
|
let key = this.spec as keyboards.ActiveKey;
|
|
this.square.style.width = vkbd.layoutWidth.scaledBy(key.proportionalWidth).styleString;
|
|
this.square.style.marginLeft = vkbd.layoutWidth.scaledBy(key.proportionalPad).styleString;
|
|
this.btn.style.width = vkbd.usesFixedWidthScaling ? this.square.style.width : '100%';
|
|
|
|
if(vkbd.usesFixedHeightScaling) {
|
|
// Matches its row's height.
|
|
this.square.style.height = vkbd.internalHeight.scaledBy(this.row.heightFraction).styleString;
|
|
} else {
|
|
this.square.style.height = '100%'; // use the full row height
|
|
}
|
|
|
|
super.refreshLayout(vkbd);
|
|
|
|
let util = com.keyman.singleton.util;
|
|
const device = vkbd.device;
|
|
const resizeLabels = (device.OS == utils.OperatingSystem.iOS &&
|
|
device.formFactor == utils.FormFactor.Phone
|
|
&& util.landscapeView());
|
|
|
|
// Rescale keycap labels on iPhone (iOS 7)
|
|
if(resizeLabels && this.capLabel) {
|
|
this.capLabel.style.fontSize = '6px';
|
|
}
|
|
}
|
|
|
|
public get displaysKeyCap(): boolean {
|
|
return this.capLabel && this.capLabel.style.display == 'block';
|
|
}
|
|
|
|
public set displaysKeyCap(flag: boolean) {
|
|
if(!this.capLabel) {
|
|
throw new Error("Key element not yet constructed; cannot display key cap");
|
|
}
|
|
this.capLabel.style.display = flag ? 'block' : 'none';
|
|
}
|
|
}
|
|
}
|