build/ui.vk.js
zebkit.package("ui.vk", function(pkg, Class) {
var ui = zebkit.ui;
pkg.$vk = null;
pkg.makeEditorVisible = true;
pkg.KeyEvent = Class(ui.event.KeyEvent, [
function $prototype() {
this.withMasks = function(masks) {
this.altKey = false;
this.shiftKey = false;
this.ctrlKey = false;
this.metaKey = false;
for(var k in masks) {
this[k] = masks[k];
}
};
}
]);
/**
* Virtual keyboard implementation
* @class zebkit.ui.vk
* @access package
*/
pkg.VKLayout = Class(zebkit.layout.Layout, [
function $prototype () {
this.ratio = this.gap = 2;
this.doLayout = function(t) {
var m = this.keyboardMetrics(t),
rows = m.rows,
row = -1,
x = 0,
y = 0,
i = 0,
r = null,
left = t.getLeft(),
top = t.getTop(),
ew = t.width - left - t.getRight(),
extra = 1000000;
// compute extra alignment for fixed size keys to
// take larger than preferred size horizontal
// space
for(i = 0; i < rows.length; i++) {
if (rows[i].fixKeys !== 0) {
r = rows[i];
var w = (r.keys > 0 ? r.keys - 1 : 0) * this.gap + m.fixKeyWidth * r.fixKeys + r.occupiedHorSpace,
ex = ew - w;
ex = Math.round(ex/r.fixKeys);
if (extra > ex) {
extra = ex;
}
}
}
// calculate final fixed size key size
if (extra !== 1000000 && extra !== 0) {
m.fixKeyWidth += extra;
// check if key proportion is good, otherwise again correct fixed key size
if (m.fixKeyWidth / m.rowHeight > this.ratio) {
m.fixKeyWidth = Math.floor(m.rowHeight * this.ratio);
}
// re-calculate keyboard width
m.width = this.maxRowWidth(rows, m.fixKeyWidth);
}
for (i = 0; i < t.kids.length; i++) {
var k = t.kids[i], ctr = k.constraints;
r = m.rows[ctr.row];
if (row !== ctr.row) {
row ++;
y += (row === 0 ? top : this.gap + m.rowHeight);
// compute actual width the row occupies
var aw = r.fixKeys * m.fixKeyWidth + r.occupiedHorSpace + (r.keys > 0 ? r.keys - 1 : 0) * this.gap;
if (r.stretchedKeys === 0) {
x = left + Math.floor((ew - aw) / 2);
} else {
x = left + Math.floor((ew - m.width) / 2);
extra = Math.floor((m.width - aw) / r.stretchedKeys);
}
}
if (k.isVisible === true) {
if (ctr.size === undefined || ctr.size === null) {
k.setSize(m.fixKeyWidth, m.rowHeight);
} else {
var ps = k.getPreferredSize();
if (ctr.size === "stretched") {
k.setSize(ps.width + extra, m.rowHeight);
} else {
k.setSize(ps.width, m.rowHeight);
}
}
k.setLocation(x, y);
x += this.gap + k.width;
}
}
};
this.calcPreferredSize = function(t) {
var m = this.keyboardMetrics(t);
return {
width : m.width,
height: m.height
};
};
this.maxRowWidth = function(rows, fixKeyWidth) {
// calculate preferred size
var width = 0;
for(var i = 0; i < rows.length; i++) {
var r = rows[i],
w = (r.keys > 0 ? r.keys - 1 : 0) * this.gap + fixKeyWidth * r.fixKeys + r.occupiedHorSpace;
if (w > width) {
width = w;
}
}
return width;
};
this.keyboardMetrics = function(t) {
var rows = [],
rowHeight = 0,
fixKeyWidth = 0;
for(var row = 0; ;row++) {
var r = this.rowMetric(row, t);
if (r === null) {
break;
}
rows.push(r);
if (r.fixKeyMaxWidth > fixKeyWidth) {
fixKeyWidth = r.fixKeyMaxWidth;
}
if (r.rowHeight > rowHeight) {
rowHeight = r.rowHeight;
}
}
// check if key proportion is good, otherwise again correct fixed key size
if (fixKeyWidth / rowHeight > this.ratio) {
fixKeyWidth = Math.floor(rowHeight * this.ratio);
}
return {
rows : rows,
rowHeight : rowHeight,
fixKeyWidth : fixKeyWidth,
width : this.maxRowWidth(rows, fixKeyWidth),
height : rows.length * rowHeight + (rows.length > 0 ? rows.length - 1 : 0) * this.gap
};
};
this.rowMetric = function(row, t) {
var fixKeys = 0,
prefKeys = 0,
stretchedKeys = 0,
fixKeyMaxWidth = 0,
occupiedHorSpace = 0,
rowHeight = 0,
stretchedHorSpace = 0,
ctr = null;
for (var i=0; i < t.kids.length; i++) {
var k = t.kids[i];
ctr = k.constraints;
// next row detected
if (ctr !== null && ctr.row > row) {
break;
}
if (ctr.row === row && k.isVisible === true) {
var ps = k.getPreferredSize();
if (ctr.size === undefined || ctr.size === null) {
if (fixKeyMaxWidth < ps.width) {
fixKeyMaxWidth = ps.width;
}
fixKeys ++;
} else {
if (ctr.size === "ps") {
prefKeys++;
} else {
stretchedKeys++;
stretchedHorSpace += ps.width;
}
occupiedHorSpace += ps.width;
}
if (rowHeight < ps.height) {
rowHeight = ps.height;
}
}
}
// no row exists
if (ctr === null || ctr.row < row) {
return null;
}
return {
keys : fixKeys + prefKeys + stretchedKeys,
fixKeys : fixKeys,
prefKeys : prefKeys,
stretchedKeys : stretchedKeys,
rowHeight : rowHeight,
fixKeyMaxWidth : fixKeyMaxWidth,
occupiedHorSpace : occupiedHorSpace,
stretchedHorSpace: stretchedHorSpace
};
};
}
]);
pkg.ShiftKeyArrow = zebkit.Class(zebkit.draw.Shape, [
function $prototype() {
this.prefSize = 10;
// / \A
// / \
// / \
// / C F \
// B ^^^| |^^^ G
// |__|
// D E
//
// Proportions:
// AC = FG = w / 4
// CF = w / 2
// w = h / 2
this.outline = function(g,x,y,w,h,d) {
x += 4;
y += 4;
w -= 8;
h -= 8;
var cx = x + Math.floor(w / 2),
ww = Math.floor(h / 2),
dw = Math.floor(h / 4),
dt = this.lineWidth / 2;
g.beginPath();
g.moveTo(cx, y); // A
g.lineTo(cx - ww + dt, y + ww + dt); // B
g.lineTo(cx - dw - dt, y + ww + dt); // C
g.lineTo(cx - dw - dt, y + h - dt); // D
g.lineTo(cx + dw + dt, y + h - dt); // E
g.lineTo(cx + dw + dt, y + ww + dt); // F
g.lineTo(cx + ww - dt, y + ww + dt); // G
g.lineTo(cx, y); // A
return true;
};
this.getPreferredSize = function() {
return {
width : this.prefSize,
height: this.prefSize
};
};
}
]);
pkg.HintPan = Class(ui.Panel, [
function() {
this.$super();
this.add(new this.clazz.Label(""));
},
function $clazz() {
this.Label = Class(ui.Label, []);
},
function setValue(v) {
this.kids[0].setValue(v);
}
]);
var tooltip = null;
pkg.VKeyBase = Class(ui.Button, [
function(v) {
if (zebkit.isString(v) === false &&
zebkit.instanceOf(v, ui.Panel) === false &&
(v instanceof Image) === false)
{
v = zebkit.draw.$view(v);
if (zebkit.instanceOf(v, zebkit.draw.ViewSet)) {
this.statusViews = v;
this.statusViewKeys = [];
this.statusKeyIndex = 0;
for(var k in v.views) {
this.statusViewKeys.push(k);
}
this.statusViews.activate(this.statusViewKeys[0]);
}
v = new ui.ViewPan().setView(v);
this.$super(v);
this.setStackLayout();
} else {
this.$super(v);
}
},
function $clazz() {
this.padding = 1;
this.Label = Class(ui.Label, []);
this.Label.font = new zebkit.Font("Arial", "bold", 14);
},
function $prototype() {
this.$isVkElement = true;
this.canHaveFocus = false;
this.statusViews = null;
this.showHint = function(ch) {
this.hideHint();
if (tooltip === null) {
tooltip = new pkg.HintPan();
}
tooltip.setValue(ch);
tooltip.toPreferredSize();
var rl = zebkit.layout.toParentOrigin(this);
if (rl.y - tooltip.height > 0) {
tooltip.setLocation(rl.x, rl.y - tooltip.height);
} else {
tooltip.setLocation(rl.x, rl.y + this.height);
}
tooltip.setSize(this.width, tooltip.height);
ui.showWindow(this, "info", tooltip);
};
this.hideHint = function() {
if (tooltip !== null) {
tooltip.removeMe();
}
};
this.findVK = function(id) {
var p = this.parent;
while (p !== null && p[id] === undefined) {
p = p.parent;
}
return p;
};
this.setLabel = function(l) {
if (zebkit.instanceOf(this.kids[0], ui.Label)) {
this.kids[0].setValue(l);
}
};
this.getLabel = function() {
return zebkit.instanceOf(this.kids[0], ui.Label) ? this.kids[0].getValue() : null;
};
this.nextStatusView = function() {
if (this.statusViews !== null) {
this.statusKeyIndex = (this.statusKeyIndex + 1) % this.statusViewKeys.length;
this.statusViews.activate(this.statusViewKeys[this.statusKeyIndex]);
this.repaint();
}
};
},
function pointerPressed(e) {
this.$super(e);
this.nextStatusView();
}
]);
// 1) "A" single character key
// { ch: "A" }
//
// 2) General virtual key pattern
// {
// ch : <ch>,
// code: <code>,
// mask: "altKey",
// label | view | icon : <?>
// }
//
// 3) Character shortcut:
// "A"
//
// 4) Multiple single char VK variants:
// "ABCD"
//
// 5) Multiple character single key
// [ "AA" ] or with variants [ "AA", ["BB"], ["CC"] ]
//
pkg.VKey = Class(pkg.VKeyBase, [
function(t) {
if (zebkit.isString(t)) {
t = { ch : t };
}
this.mask = t.mask === undefined ? null : t.mask;
this.ch = t.ch === undefined ? null : t.ch;
this.code = t.code === undefined ? 0 : t.code;
this.hint = t.hint === undefined ? null : t.hint;
this.repeat = t.repeat === undefined ? false : t.repeat;
if (this.repeat !== false) {
this.setFireParams(true, t.repeat);
}
this.$super(t.view || t.icon || t.label || this.ch);
},
function $prototype() {
this.$sticked = false;
this.$syncMask = function(mask, value) {
if (this.mask === mask && value === true) {
this.$sticked = !this.$sticked;
this.setState(this.$sticked ? "pressed.over" : "over");
this.nextStatusView();
}
};
this.fired = function() {
if (this.ch !== null) {
this.fireVkTyped(this.code, this.ch, this.mask);
} else {
// handle period keys
if (this.firePeriod > 0 &&
this.$repeatTask !== null &&
this.$repeatTask.isStarted === true)
{
this.fireVkPressed(this.code, this.ch, this.mask);
}
}
};
this.fireVkTyped = function(code, ch, mask) {
var vk = this.findVK("vkTyped");
if (vk !== null) {
vk.vkTyped(this, code, ch, mask);
}
};
this.fireVkReleased = function(code, ch, mask) {
this.hideHint();
var vk = this.findVK("vkReleased");
if (vk !== null) {
vk.vkReleased(this, code, ch, mask);
}
};
this.fireVkPressed = function(code, ch, mask) {
var vk = this.findVK("vkPressed");
if (vk !== null) {
vk.vkPressed(this, code, ch, mask);
}
if (ch !== null && this.hint !== null) {
this.showHint(this.hint !== null ? ch : this.hint);
}
};
this.upperCase = function() {
if (this.ch !== null) {
var l = this.getLabel();
if (l !== null && l.toLowerCase() === this.ch.toLowerCase()) {
this.setLabel(l.toUpperCase());
}
}
};
this.lowerCase = function() {
if (this.ch !== null) {
var l = this.getLabel();
if (l !== null && l.toLowerCase() === this.ch.toLowerCase()) {
this.setLabel(l.toLowerCase());
}
}
};
},
function _pointerPressed(e) {
if (this.$sticked === true) {
this.$sticked = false;
this.$getSuper("_pointerReleased").call(this, e);
this.fireVkReleased(this.code, this.ch, this.mask);
} else {
this.$super(e);
this.fireVkPressed(this.code, this.ch, this.mask);
if (this.mask !== null) {
this.$sticked = true;
}
}
},
function _pointerReleased(e) {
if (this.mask === null) {
this.$super(e);
this.fireVkReleased(this.code, this.ch, this.mask);
}
}
]);
pkg.ArrowView = Class(zebkit.draw.ArrowView, [
function $prototype() {
this.gap = 0;
this.color = "white";
}
]);
pkg.PredefinedVKey = {
shift : {
view: {
"on" : new pkg.ShiftKeyArrow(),
"off": new pkg.ShiftKeyArrow()
},
code : "Shift",
mask : "shiftKey"
},
left: {
code : "ArrowLeft",
view : new pkg.ArrowView("left"),
firePeriod: 150
},
right: {
code : "ArrowRight",
view : new pkg.ArrowView("right"),
repeat: 150
},
up: {
code : "ArrowUp",
view : new pkg.ArrowView("top"),
repeat: 150
},
down: {
code : "ArrowDown",
view : new pkg.ArrowView("bottom"),
repeat: 150
},
enter : {
// | A
// E |
// C /______| B
// \ D
//
view: zebkit.draw.$view(function(g, x, y, w, h, d) {
var gap = 6;
g.setColor("orange");
g.beginPath();
g.lineWidth = 2;
g.moveTo(x + w - gap, y + gap); // A
g.lineTo(x + w - gap, y + h - 2*gap); // AB
g.lineTo(x + gap, y + h - 2*gap); // BC
g.lineTo(x + 2*gap, y + h - gap); // CD
g.moveTo(x + gap - 1, y + h - 2*gap); // C
g.lineTo(x + 2*gap, y + h - 3 * gap); // CE
g.stroke();
}),
ch : "\n",
hint: null
},
space : {
label: "Space",
ch : " ",
size : "stretched",
hint : null
},
backspace: {
code: "Backspace",
label: "<=",
view2: zebkit.draw.$view(function(g, x, y, w, h, d) {
g.setColor("black");
g.beginPath();
g.lineWidth = 2;
g.moveTo(x + w - 2, y + h - 8); // B
g.lineTo(x + 6, y + h - 8); // BC
g.lineTo(x + 12, y + h - 4); // CD
g.moveTo(x + 6, y + h - 8); // C
g.lineTo(x + 12, y + h -12); // CE
g.stroke();
}),
repeat: 150,
size: "ps",
hints: "backspace"
}
};
pkg.VKeyOption = Class(pkg.VKeyBase, [
function (v, options) {
this.$super(v);
this.menu = new this.clazz.Menu(options);
this.menu.toPreferredSize();
this.menu.$isVkElement = true;
this.options = options.slice(0);
var $this = this;
this.menu.on(function(src, i) {
if (src.selectedIndex >= 0) {
var vk = $this.findVK("vkOptionSelected");
if (vk !== null) {
vk.vkOptionSelected($this,
src.selectedIndex,
$this.options[src.selectedIndex]);
}
}
});
},
function $clazz() {
this.Menu = Class(ui.Menu, [
function $prototype() {
this.canHaveFocus = false;
}
]);
},
function $prototype() {
this.fired = function() {
if (this.menu.parent !== null) {
this.menu.removeMe();
} else {
var o = zebkit.layout.toParentOrigin(this);
this.menu.select(-1);
this.menu.toPreferredSize();
this.menu.setLocation(o.x, o.y - this.menu.height);
ui.showPopupMenu(this, this.menu);
}
};
}
]);
var RL = Class(zebkit.layout.RasterLayout, [
function calcPreferredSize(t) {
var w = 0, h = 0;
for (var i = 0; i < t.kids.length; i++) {
if (t.kids[i].isVisible === true) {
var ps = t.kids[i].getPreferredSize();
w += ps.width;
h += ps.height;
}
}
return { width: w, height: h };
}
]),
KE = new pkg.KeyEvent();
KE.device = "vkeyboard";
pkg.VKeys = Class(pkg.VKey, [
function(chars) {
if (chars.length < 2) {
throw new Error();
}
this.$super( {
ch : chars[0],
label : new this.clazz.KeysLabelPan(chars)
});
if (chars.length > 2) {
this.keysPopupPan = new this.clazz.KeysPopupPan();
var $this = this;
for(var i = 1; i < chars.length; i++) {
var key = pkg.createVKey(chars[i]);
key.extend([
function findVK(id) {
return $this.findVK(id);
},
function fireVkReleased(code, ch, mask) {
this.$super(code, ch, mask);
$this.hideKeysPopupPan();
}
]);
this.keysPopupPan.add(key);
}
} else {
this.altCh = chars[1];
}
},
function $clazz () {
this.layout = new zebkit.layout.BorderLayout();
this.SmallLabel = Class(ui.Label, []);
this.SmallLabel.font = new zebkit.Font(pkg.VKey.Label.font.name, Math.floor((2*pkg.VKey.Label.font.height)/3));
this.KeysPopupPan = Class(ui.Panel, [
function $clazz() {
this.layout = new zebkit.layout.FlowLayout("left", "center", "horizontal", 6);
this.padding = 6;
this.border = new zebkit.draw.Border("plain");
this.background = "rgba(200,200,200,0.8)";
},
function $prototype() {
this.$dontGrabFocus = this.$isVkElement = true;
},
function() {
this.$super();
}
]);
this.KeysLabelPan = Class(ui.Panel, [
function $clazz() {
this.layout = new RL(true);
},
function(chars) {
this.$super();
this.constraints = "center";
var mainLab = new pkg.VKeys.Label(chars[0]),
altLab = new pkg.VKeys.SmallLabel(chars.length === 2 ? chars[1] : "...");
mainLab.constraints = "center";
altLab.constraints = "topRight";
this.add(mainLab);
this.add(altLab);
this.mainLab = mainLab;
}
]);
},
function $prototype() {
this.keysPopupPan = null;
this.getLabel = function() {
return this.kids[0].mainLab.getValue();
};
this.setLabel = function(l) {
this.kids[0].mainLab.setValue(l);
};
this.showKeysPopupPan = function() {
this.hideHint();
if (this.keysPopupPan === null) {
this.$counter = (this.$counter + 1 ) % 2;
this.showHint(this.$counter === 0 ? this.ch : this.altCh);
} else {
this.$pressed.shutdown();
var rl = zebkit.layout.toParentOrigin(this);
for(var i = 0; i < this.keysPopupPan.kids.length; i++) {
this.keysPopupPan.kids[i].setPreferredSize(this.width, this.height);
}
this.keysPopupPan.toPreferredSize();
this.keysPopupPan.setLocation(rl.x, rl.y - this.keysPopupPan.height);
this.keysPopupPan.winActivated = function(e) {
if (e.isActive === false) {
e.source.removeMe();
}
};
ui.showWindow(this, "mdi", this.keysPopupPan);
ui.makeFullyVisible(this.keysPopupPan);
ui.activateWindow(this.keysPopupPan);
this.setState("out");
}
};
this.hideKeysPopupPan = function() {
if (this.keysPopupPan !== null) {
this.keysPopupPan.removeMe();
}
};
},
function fireVkPressed(code, ch, mask) {
this.$counter = 0;
this.hideKeysPopupPan();
this.$super(code, ch, mask);
var $this = this;
this.$pressed = zebkit.util.tasksSet.run(function(t) {
$this.showKeysPopupPan(t);
}, 700, 700);
},
function fireVkTyped(code, ch, mask) {
if (this.keysPopupPan === null) {
ch = this.$counter > 0 ? this.altCh : this.ch;
this.$super(ch.charCodeAt(0), ch, mask);
} else if (this.keysPopupPan.parent === null) {
this.$super(code, ch, mask);
}
},
function fireVkReleased(code, ch, mask) {
this.$pressed.shutdown();
this.$super(code, ch, mask);
}
]);
pkg.showVK = function(input) {
pkg.$vk.show(input);
};
pkg.getVK = function() {
return pkg.$vk;
};
pkg.createVKey = function(d) {
if (zebkit.isString(d)) {
if (pkg.PredefinedVKey.hasOwnProperty(d.toLowerCase())) {
d = pkg.PredefinedVKey[d.toLowerCase()];
} else if (d.length > 1) {
return new pkg.VKeys(d);
}
} else if (Array.isArray(d)) {
return d.length === 1 ? new pkg.VKey (d[0])
: new pkg.VKeys(d);
} else if (d.hasOwnProperty("vkey")) {
return d.vkey;
}
return new pkg.VKey(d);
};
pkg.VK = Class(ui.Panel, [
function() {
this.$super();
this.masks = {
shiftKey : false,
metaKey : false,
ctrlKey : false,
altKey : false
};
},
function $prototype() {
this.$dontGrabFocus = true;
this.eachGroupKey = function(g, f) {
g = this.getGroupPan(g);
if (g !== null) {
for(var i = 0; i < g.kids.length; i++) {
var k = g.kids[i];
f.call(this, g, k);
}
}
};
this.eachKey = function(f) {
for(var i = 0; i < this.kids.length; i++) {
this.eachGroupKey(this.kids[i].name, f);
}
};
this.show = function(d) {
this.removeMe();
if (d !== null) {
this.constraints = "bottom";
this.toPreferredSize();
if (pkg.makeEditorVisible === true) {
var p = zebkit.layout.toParentOrigin(d);
if (p.y + d.height > this.height) {
this.constraints = "top";
}
}
ui.showWindow(d, "mdi", this);
var win = this.getCanvas().getLayer("win");
this.setSize(win.width - win.getLeft() - win.getRight(), this.height);
ui.activateWindow(this);
}
};
this.onMask = function(mask, vk) {
if (mask !== null && (this.masks.hasOwnProperty(mask) === false || this.masks[mask] !== true)) {
this.masks[mask] = true;
this.vkMaskUpdated(vk, mask, true);
}
};
this.offMask = function(mask, vk) {
if (mask !== null && this.masks.hasOwnProperty(mask) && this.masks[mask] === true) {
this.masks[mask] = false;
this.vkMaskUpdated(vk, mask, false);
}
};
this.vkOptionSelected = function(vkey, index, option) {
this.fire("vkOptionSelected", [vkey, index, option]);
};
this.hasMaskSet = function(mask) {
if (mask.match(/^[a-z]+Key$/) === null) {
throw new Error("Invalid mask '" + mask + "'");
}
return this.masks.hasOwnProperty(mask) && this.masks[mask] === true;
};
this.vkMaskUpdated = function(vkey, mask, value) {
if (mask === undefined || mask === null) {
throw new Error();
}
this.eachKey(function(group, key) {
if (key !== vkey && key.mask !== null && key.mask === mask) {
key.$syncMask(mask, value);
}
});
this.fire("vkMaskUpdated", [vkey, mask, value]);
};
this.vkPressed = function (vk, code, key, mask) {
if (mask !== null) {
this.onMask(mask, vk);
}
KE.key = key;
KE.code = code;
KE.withMasks(this.masks);
this.getCanvas().$keyPressed(KE);
};
this.vkTyped = function (vk, code, key, mask) {
KE.key = this.hasMaskSet("shiftKey") ? key.toUpperCase() : key;
KE.code = code;
KE.withMasks(this.masks);
this.getCanvas().$keyTyped(KE);
};
this.vkReleased = function(vk, code, key, mask) {
if (mask !== null) {
this.offMask(mask, vk);
}
KE.key = key;
KE.code = code;
KE.withMasks(this.masks);
this.getCanvas().$keyReleased(KE);
};
this.setActiveGroup = function(name) {
if (this.group !== name) {
this.group = name;
for(var i = 0; i < this.kids.length; i++) {
var k = this.kids[i];
k.setVisible(k.name === name);
}
// adjust size if VK is shown
var can = this.getCanvas();
if (can !== null && can.hasOwnProperty("win") === true) {
var win = can.getLayer("win");
this.toPreferredSize();
this.setSize(win.width - win.getLeft() - win.getRight(), this.height);
}
}
};
this.getGroupPan = function(name) {
for(var i = 0; i < this.kids.length; i++) {
var k = this.kids[i];
if (k.name === name) {
return k;
}
}
return null;
};
this.setGroups = function(groups) {
for(var k in groups) {
if (groups.hasOwnProperty(k)) {
this.addGroup(k, groups[k]);
}
}
};
this.addGroup = function(name, layout) {
var group = new ui.Panel(new pkg.VKLayout());
group.name = name;
for(var row = 0; row < layout.length; row++) {
var r = layout[row];
for(var col = 0; col < r.length; col++) {
var v = r[col];
if (zebkit.isString(v)) {
if (pkg.PredefinedVKey.hasOwnProperty(v)) {
v = pkg.PredefinedVKey[v];
}
}
group.add({
row : row,
size: v.size
}, pkg.createVKey(v));
}
}
this.add(group);
};
},
function setParent(p) {
// mean the vk is removed from its parent
if (p === null && this.parent !== null) {
// remove other VK related elements
for(var i = this.parent.kids.length - 1; i >= 0; i--) {
var kid = this.parent.kids[i];
if (kid.$isVkElement === true) {
kid.removeMe();
}
}
}
this.$super(p);
}
]).events("vkMaskUpdated", "vkOptionSelected");
pkg.activateVK = function() {
pkg.$vk = new pkg.VK();
return pkg.$vk;
};
function $isVkElement(c) {
var p = c;
while (p !== null && p.$isVkElement !== true) {
p = p.parent;
}
return p !== null;
}
ui.events.on({
focusGained : function (e) {
if (pkg.$vk !== null && $isVkElement(e.source) === false && e.source.vkMode !== undefined) {
pkg.showVK(zebkit.instanceOf(e.source, ui.TextField) ? e.source : null);
}
},
pointerPressed : function(e) {
if (pkg.$vk !== null) {
if (pkg.$vk.parent !== null &&
$isVkElement(e.source) === false &&
zebkit.layout.isAncestorOf(pkg.$vk, e.source) === false)
{
pkg.showVK(null);
}
// if input component holds focus, virtual keyboard is
// hidden and we press on the input component
if (pkg.$vk.parent === null && e.source.vkMode !== undefined) {
pkg.showVK(e.source);
}
}
}
});
}, true);