diff --git a/.memory/state.md b/.memory/state.md index 0ad015f..33648ef 100644 --- a/.memory/state.md +++ b/.memory/state.md @@ -1,6 +1,6 @@ # State - Core engine: `src/rpn-calculator.js` -- Active demo: `samples/calc-02/` responsive HP48GX layout driven by portrait/landscape text mockups; display-adjacent button row stays in 4 columns +- Active demo: `samples/calc-02/` responsive HP48GX layout with HP48-like X-line editing; display-adjacent button row stays in 4 columns - Mode button shows the current angle mode only; selecting a mode uses a popup menu - Public API: `push`, `pop`, `clear`, `swap`, `remove`, `edit`, `isValidIndex`, `input`, `command`, `getOperationsByCategory`, `getConstants` - Config: `maxSize`, `base`, `angleMode`, `enabledCommands` diff --git a/samples/calc-02/index.js b/samples/calc-02/index.js index 03933df..a397d1b 100644 --- a/samples/calc-02/index.js +++ b/samples/calc-02/index.js @@ -86,8 +86,7 @@ function normalizeStack() { } function getStackLine(indexFromTop) { - const index = calc.stack.length - 1 - indexFromTop; - return index >= 0 ? calc.stack[index] : ''; + return indexFromTop >= 0 && indexFromTop < calc.stack.length ? calc.stack[indexFromTop] : ''; } function render() { @@ -95,10 +94,11 @@ function render() { const isPortrait = window.matchMedia('(orientation: portrait)').matches || window.innerWidth <= 860; calculatorEl?.classList.toggle('portrait', isPortrait); calculatorEl?.classList.toggle('landscape', !isPortrait); - stackEls.T.textContent = calc.formatNumber(getStackLine(3)) || ''; - stackEls.Z.textContent = calc.formatNumber(getStackLine(2)) || ''; - stackEls.Y.textContent = calc.formatNumber(getStackLine(1)) || ''; - stackEls.X.textContent = calc.formatNumber(getStackLine(0)) || (calc.isEditing ? calc.inputValue : ''); + const editingValue = calc.isEditing ? calc.inputValue : ''; + stackEls.X.textContent = calc.isEditing ? editingValue : (calc.formatNumber(getStackLine(0)) || ''); + stackEls.Y.textContent = calc.isEditing ? (calc.formatNumber(getStackLine(0)) || '') : (calc.formatNumber(getStackLine(1)) || ''); + stackEls.Z.textContent = calc.isEditing ? (calc.formatNumber(getStackLine(1)) || '') : (calc.formatNumber(getStackLine(2)) || ''); + stackEls.T.textContent = calc.isEditing ? (calc.formatNumber(getStackLine(2)) || '') : (calc.formatNumber(getStackLine(3)) || ''); modeButton.textContent = calc.angleMode; } @@ -129,7 +129,11 @@ function inputToX(value) { function execute(name) { try { if (name === 'enter') { - pushEditingValueIfNeeded(); + if (calc.isEditing) { + pushEditingValueIfNeeded(); + } else if (calc.isValidIndex(0)) { + calc.push(calc.stack[0]); + } } else if (name === 'clear') { calc.clear(); calc.inputValue = ''; @@ -143,6 +147,11 @@ function execute(name) { } else { calc.remove(0); } + } else if (name === 'swap') { + pushEditingValueIfNeeded(); + if (calc.isValidIndex(1)) { + calc.swap(0, 1); + } } else if (name === 'neg') { if (calc.isEditing) { calc.inputValue = calc.inputValue.startsWith('-') ? calc.inputValue.slice(1) : `-${calc.inputValue}`; @@ -349,7 +358,10 @@ leftButton.addEventListener('click', () => {}); downButton.addEventListener('click', () => {}); -rightButton.addEventListener('click', () => {}); +rightButton.addEventListener('click', () => { + execute('swap'); +}); + window.addEventListener('keydown', handleKeyboard); window.addEventListener('load', focusInput);