diff --git a/calculator/calculator.app.js b/calculator/calculator.app.js index 5c04ffc..268c81d 100644 --- a/calculator/calculator.app.js +++ b/calculator/calculator.app.js @@ -12,7 +12,6 @@ require("FontDylex7x13").add(Graphics); var DEFAULT_SELECTION_NUMBERS = '5'; var RESULT_HEIGHT = 40; -var RESULT_MAX_LEN = Math.floor((g.getWidth() - 20) / 16); var COLORS = { // [normal, selected] DEFAULT: ['#7F8183', '#A6A6A7'], @@ -218,6 +217,7 @@ function doMath(x, y, operator) { function displayOutput(num) { g.setBgColor(0).clearRect(0, 0, g.getWidth(), RESULT_HEIGHT-1); g.setColor(-1); + g.setFont('Dylex7x13', 2); if (num === Infinity || num === -Infinity || isNaN(num)) { // handle division by 0 if (num === Infinity) { @@ -235,7 +235,6 @@ function displayOutput(num) { operator = null; specials.R.val = 'AC'; if (!swipeEnabled) drawKey('R', specials.R); - g.setFont('Dylex7x13', 2); } else { // might not be a number due to display of dot "." var numNumeric = Number(num); @@ -253,27 +252,36 @@ function displayOutput(num) { } } var numStr = num.toString(); - if (typeof num === 'number' && (numStr.length > RESULT_MAX_LEN || (num !== 0 && Math.abs(num) < 1e-4))) { - // dynamic precision based on exponent length - var exp = Math.floor(Math.log(Math.abs(num)) / Math.LN10); - var expLen = String(Math.abs(exp)).length; - var signLen = (num < 0) ? 1 : 0; - // Total length is sign + first-digit + dot + fraction + E + exp-sign + exp-digits - // So precision for fraction is MAX - (sign + first-digit + dot + E + exp-sign + exp-digits) - let precision = RESULT_MAX_LEN - (signLen + 1 + 1 + 1 + 1 + expLen); - if (precision < 0) precision = 0; - num = toExponential(num, precision).replace("e", "E"); - } else { - num = addSeparators(numStr); + var displayStr = addSeparators(numStr); + + if (typeof num === 'number' && (g.stringWidth(displayStr) > g.getWidth() - 20 || (num !== 0 && Math.abs(num) < 1e-4))) { + // try to format as scientific notation + let precision = 10; // start with high precision + while (precision >= 0) { + let scientificStr = toExponential(num, precision).replace("e", "E"); + if (g.stringWidth(scientificStr) <= g.getWidth() - 20) { + displayStr = scientificStr; + break; + } + precision--; + } + if (precision < 0) { // if it still doesn't fit + displayStr = toExponential(num, 0).replace("e", "E"); + } } + num = displayStr; + + // final check for truncation + if (g.stringWidth(num) > g.getWidth() - 20) { + while(g.stringWidth(num+'...') > g.getWidth() - 20 && num.length > 1) { + num = num.slice(0,-1); + } + num += '...'; + } + if (num.charAt(0) === '-') { num = '- ' + num.substr(1); } - g.setFont('Dylex7x13', 2); - if (num.length > RESULT_MAX_LEN) { - if (num.indexOf("E") < 0) - num = num.substr(0, RESULT_MAX_LEN - 1)+'...'; - } } g.setFontAlign(1,0); g.drawString(num, g.getWidth()-20, RESULT_HEIGHT/2);