suranadira-keyboard
Version:
A component for displaying Suranadira texts.
520 lines (399 loc) • 16.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function get() {
return _SuranadiraKeyboard.default;
}
});
var _SuranadiraKeyboard = _interopRequireDefault(require("./SuranadiraKeyboard"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.updateComposition = void 0;
var _suranadiraCore = _interopRequireDefault(require("../../suranadira-core"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var words = _suranadiraCore.default.suranadiraWords.suranadiraWords; // Get initial layout values
function _getInitialLayout(truthValue) {
var values = new Set();
for (var word in words) {
if (words[word].values[0] === truthValue) {
values.add(words[word].elements[0][0]);
}
}
return values;
} // Get next layout
var _getNextLayout = function _getNextLayout(composition) {
if (composition.length > 3) return;
var layout = new Set();
var t = composition;
var tp = JSON.stringify(t);
var len = composition.length;
var a = [];
for (var word in words) {
for (var n = 0; n < len; n++) {
a.push(words[word].elements[n][0]);
}
if (tp === JSON.stringify(a)) {
layout.add(words[word].elements[len][0]);
}
a = [];
}
return layout;
}; // Update the composition according to the new key ID
// return 1) the new layout and 2) the updated composition
var updateComposition = function updateComposition(keyID, position, layout, composition) {
if (keyID === "") return;
if (position > -1) {
// Get keyboard layout by composition
var index = parseInt(keyID, 10);
var a = Array.from(layout);
if (index > a.length - 1) return false;
composition.push(a[index]);
layout = _getNextLayout(composition);
} else {
// Get initial keyboard layout by truth value
var truthValue = parseInt(keyID, 10);
if (truthValue !== 0 && truthValue !== 1) return false;
layout = _getInitialLayout(truthValue);
}
return [layout, composition];
};
exports.updateComposition = updateComposition;
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _suranadiraCore = _interopRequireDefault(require("../../suranadira-core"));
var _debug = _interopRequireWildcard(require("suranadira-utils/debug"));
var _dom = require("suranadira-utils/dom");
var _arrays = require("suranadira-utils/arrays");
var _keyboard = require("suranadira-utils/keyboard");
var _string = require("suranadira-utils/string");
var _canvas = require("suranadira-utils/canvas");
var _keyboardLayout = require("./keyboard-layout");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
var strokes = _suranadiraCore.default.suranadiraStrokes;
var elements = _suranadiraCore.default.suranadiraElements;
var getWordID = _suranadiraCore.default.suranadiraWords.getWordID; // Control commands
var showKeyNames = false; // The Keyboard app
var SuranadiraKeyboard = function SuranadiraKeyboard(args) {
// Defaults
var defaults = {
width: window.innerWidth,
maxWidth: 900,
height: 80,
color: "#000",
colorPressed: "#ff0000",
background: "#ddd",
keyWidth: 7,
keyHeight: 7,
onClickAllowed: true,
onKeyDownAllowed: true,
onComposition: function onComposition() {},
onLayoutSet: function onLayoutSet() {},
layoutDefault: new Set(["Z", "J"]),
unit: 20,
lineWidth: 5,
charSpaceX: 6,
charSpaceY: 3,
focusRectPaddingX: -2,
focusRectPaddingY: 0,
locked: false,
visible: true,
resize: "",
styles: {}
}; // Properties
var properties = Object.assign(defaults, args);
if (typeof args.styles !== "undefined") {
properties = Object.assign(properties, args.styles);
}
properties.height = properties.unit * 4; // Limit component's width
if (properties.width > properties.maxWidth) properties.width = properties.maxWidth; // Create canvas reference
var refCanvas = _react.default.createRef(); // External hooks
var keyDown = (0, _keyboard.useKeyDown)(); // Define state hooks
var _useState = (0, _react.useState)(-1),
_useState2 = _slicedToArray(_useState, 2),
position = _useState2[0],
setPosition = _useState2[1]; // as in "positional number system"
var _useState3 = (0, _react.useState)([]),
_useState4 = _slicedToArray(_useState3, 2),
composition = _useState4[0],
setComposition = _useState4[1];
var _useState5 = (0, _react.useState)(properties.layoutDefault),
_useState6 = _slicedToArray(_useState5, 2),
layout = _useState6[0],
setLayout = _useState6[1];
var _useState7 = (0, _react.useState)(null),
_useState8 = _slicedToArray(_useState7, 2),
paths = _useState8[0],
setPaths = _useState8[1]; // Set the default layout
(0, _react.useEffect)(function () {
drawLayout(properties.layoutDefault);
setLayout(properties.layoutDefault); // eslint-disable-next-line
}, []); // Dispatcher for externale commands
(0, _react.useEffect)(function () {
if (!properties.action) return; // Send out the script
switch ((0, _string.removeUID)(properties.action)) {
// On Composition done
case "DONE":
(0, _debug.default)((0, _debug.info)({
module: "SuranadiraKeyboard.js",
func: "useEffect [properties.action]",
param: "composition",
value: composition
}));
properties.onDone(composition);
resetKeyboard();
break;
// On Composition cancelled
case "CANCEL":
properties.onCancel();
resetKeyboard();
break;
// On Message sent
case "SENT":
resetKeyboard();
break;
default:
// ignore
break;
} // eslint-disable-next-line
}, [properties.action]); // Map keyDown to virtual keyDown
(0, _react.useEffect)(function () {
if (properties.locked) return; // Unserialze the keyDown return
var keyID = (0, _string.removeUID)(keyDown); // Show the keyID in console
if (showKeyNames) console.log(keyID); // Map a physical numeric key to virtual keyboard
if (!isNaN(parseFloat(keyID)) && isFinite(keyID)) {
onKeyDown(keyID);
} // Finalize Composition
else if (keyID === "Enter") {
properties.onDone(composition);
resetKeyboard();
} // Cancel Composition
else if (keyID === "Escape") {
properties.onCancel();
resetKeyboard();
} // eslint-disable-next-line
}, [keyDown]); // Handle the device dimensions change
(0, _react.useEffect)(function () {
(0, _debug.default)((0, _debug.info)({
module: "SuranadiraKeyboard.js",
func: "useEffect [properties.resize]",
param: "layout",
value: layout
}));
drawLayout(layout); // eslint-disable-next-line
}, [properties.resize]); // Fire event onLayoutSet
(0, _react.useEffect)(function () {
var diff = new Set(_toConsumableArray(layout).filter(function (x) {
return !properties.layoutDefault.has(x);
}));
properties.onLayoutSet(layout, layout.size !== 0 && diff.size === 0); // eslint-disable-next-line
}, [layout]); // Map mouseClick to virtual keyDown
var onClick = function onClick(e) {
if (!properties.onClickAllowed) return;
var keyID = getKeyIDByMouseEvent(e); // Trigger key down, if a key was pressed
if (keyID !== false) onKeyDown(keyID);
};
var getKeyIDByMouseEvent = function getKeyIDByMouseEvent(e) {
// Get CTX
var canvas = refCanvas.current;
var ctx = canvas.getContext("2d"); // Get point coordinates
var point = (0, _dom.getClickXY)(e);
var x = point.x;
var y = point.y; // Get path index
var keyID = (0, _canvas.getPathIndex)({
ctx: ctx,
paths: paths,
x: x,
y: y
});
return keyID;
};
var onMouseDown = function onMouseDown(e) {
var keyID = getKeyIDByMouseEvent(e);
console.log("onMouseDown keyID", keyID);
drawElement(keyID, properties.colorPressed);
};
var onMouseUp = function onMouseUp(e) {
var keyID = getKeyIDByMouseEvent(e);
console.log("onMouseUp keyID", keyID);
drawElement(keyID, properties.color);
}; // Send the virtual keyDown to Callback
var onKeyDown = function onKeyDown(keyID) {
if (!properties.onKeyDownAllowed) return; // Compose character according to the key command
composeCharacter(keyID);
}; // Set Suranadirakeyboard layout
var drawLayout = function drawLayout(lo) {
if (typeof lo === "undefined") return; // Clear keyboard
clearKeyboard();
var _paths = [],
_path; // Draw Suranadira Elements
for (var keyID = 0; keyID < lo.size; keyID++) {
_path = drawElement(keyID, properties.color, lo);
_paths.push(_path);
}
setPaths(_paths);
setLayout(lo);
}; // Draw an Element / a Keyboard Key
var drawElement = function drawElement(keyID, color, lo) {
if (typeof lo === "undefined") lo = layout;
if (typeof color === "undefined") color = properties.color;
var ctx = getCTX();
if (!ctx) return;
var _lo = Array.from(lo);
var element = _lo[keyID];
var marginLeft = 2;
var offset = keyID * properties.keyWidth; // Stroke properties
strokes.properties.ctx = ctx;
strokes.properties.unit = properties.unit;
strokes.properties.lineWidth = properties.lineWidth;
strokes.properties.left = 0;
strokes.properties.top = properties.unit * 1.5;
strokes.properties.strokeStyle = color;
var x, shape;
try {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = elements[element].strokes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var stroke = _step.value;
shape = stroke[0];
x = stroke[1];
strokes.draw(shape, x + offset + marginLeft, 0);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
} catch (e) {} // ignore
// Set path properties
var pathProperties = {
left: (offset + marginLeft) * strokes.properties.unit - properties.focusRectPaddingX,
top: strokes.properties.top - properties.focusRectPaddingY,
width: strokes.properties.unit * properties.charSpaceX + 2 * properties.focusRectPaddingX,
height: strokes.properties.unit * properties.charSpaceY + -2 * properties.focusRectPaddingY
}; // Create path for events for the composition
var path = (0, _canvas.createPath)({
ctx: ctx,
properties: pathProperties,
invisible: true
});
return path;
}; // Compose character
var composeCharacter = function composeCharacter(keyID) {
var _layout = layout;
var _position = position;
var ret = (0, _keyboardLayout.updateComposition)(keyID, // numeric key 0..n for choice selection
position, // position within the positional number system
layout, // a set of element choices
composition // current composition of the character
); // Send composition and character ID to callback
if (ret !== false) {
var _ret = _slicedToArray(ret, 2),
co = _ret[0],
cp = _ret[1]; // Draw layout
if (_typeof(co) !== undefined) {
drawLayout(co);
_layout = co;
} // Save state
setComposition(cp);
_position = position + 1; // Callback composition
if (cp.length < 4) {
properties.onComposition((0, _arrays.encode)(cp), null);
} // Callback composition and character ID
else {
(0, _debug.default)((0, _debug.info)({
module: "SuranadiraKeyboard.js",
func: "composeCharacter",
param: "cp for getWordID(cp)",
value: cp
}));
var ch = getWordID(cp);
if (ch !== false) {
properties.onComposition((0, _arrays.encode)(cp), ch);
clearKeyboard(); // setPosition(-1);
_position = -1;
_layout = new Set();
}
}
}
setPosition(_position);
setLayout(new Set(_layout));
}; // Get canvas context
var getCTX = function getCTX() {
var canvas = refCanvas.current;
var ctx = canvas.getContext("2d");
return ctx;
}; // Clear the keyboard canvas
var clearKeyboard = function clearKeyboard() {
// let canvas = refCanvas.current;
// let ctx = canvas.getContext("2d");
var ctx = getCTX();
if (!ctx) return;
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
return ctx;
}; // Reset keyboard after composition is done
var resetKeyboard = function resetKeyboard() {
drawLayout(properties.layoutDefault);
setPosition(-1);
setComposition([]);
};
return _react.default.createElement("div", {
className: "SuranadiraKeyboard",
style: {
background: "none",
// properties.background,
position: "relative",
display: properties.visible ? "inline-block" : "none",
width: properties.width,
height: properties.height,
// boxSizing: "border-box",
overflow: "hidden"
}
}, _react.default.createElement("canvas", {
ref: refCanvas,
style: {
background: properties.background,
// "none",
position: "relative",
display: "block"
},
width: properties.width + "px",
height: properties.height + "px",
onClick: onClick,
onMouseDown: onMouseDown,
onMouseUp: onMouseUp
}));
};
var _default = SuranadiraKeyboard;
exports.default = _default;