in graphics/nxwm/src/chexcalculator.cxx [700:943]
void CHexCalculator::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
{
// A button should now be clicked
int column;
int row;
if (m_keypad->isButtonClicked(column, row))
{
// Handle the key according to its type
int index = row * NXWM_HEXCALCULATOR_NCOLUMNS + column;
// First, make sure that the keypress is valid in this mode
if ((m_hexMode && !g_keyDesc[index].hexMode) ||
(!m_hexMode && !g_keyDesc[index].decMode))
{
// Ignore the key in this mode
return;
}
// Process the keypress
bool result = false;
switch (g_keyDesc[index].keyType)
{
// Values: {0-9, A-F}
case KEY_VALUE: // Key is a value
{
// If the accumulator current holds the result of a previous
// operation, then start fresh
if (m_result)
{
m_accum = (uint64_t)g_keyDesc[index].value;
}
// Otherwise, add the new value to the accumulator. The way
// in which it is added depends on the mode
else if (m_hexMode)
{
m_accum <<= 4;
m_accum |= (uint64_t)g_keyDesc[index].value;
}
else
{
m_accum *= 10;
m_accum += (uint64_t)g_keyDesc[index].value;
}
updateText();
}
break;
// Unary operators
case KEY_NOT: // 1's complement
{
m_accum = ~m_accum;
updateText();
}
break;
case KEY_NEGATE: // 2's complement
{
m_accum = -m_accum;
updateText();
}
break;
// Low precedence Binary operators
case KEY_XOR: // Exclusive OR
case KEY_OR: // Bit-wise OR
case KEY_MINUS: // Subtraction
case KEY_PLUS: // Additions
{
// Is there a high precedence operation?
if (m_high.operation != (uint8_t)KEY_NONE)
{
m_accum = evaluateBinaryOperation(m_high.operation, m_high.value, m_accum);
m_high.operation = (uint8_t)KEY_NONE;
m_high.value = 0;
}
// Is there a pending low precedence operation?
if (m_low.operation != (uint8_t)KEY_NONE)
{
m_accum = evaluateBinaryOperation(m_low.operation, m_low.value, m_accum);
}
// Save the new low precedence operation
m_low.operation = (uint8_t) g_keyDesc[index].keyType;
m_low.value = m_accum;
// Update the display with the value in the accumulator, but
// then clear the accumulator in preparation for the next input
updateText();
m_accum = 0;
}
break;
// High precedence Binary operators
case KEY_DIVIDE: // Division
case KEY_RSH: // Right shift
case KEY_LSH: // Left shift
case KEY_MULTIPLY: // Multiplication
case KEY_AND: // Bit-wise AND
{
// Is there a high precedence operation?
if (m_high.operation != (uint8_t)KEY_NONE)
{
m_accum = evaluateBinaryOperation(m_high.operation, m_high.value, m_accum);
}
// Save the new high precedence operation
m_high.operation = (uint8_t) g_keyDesc[index].keyType;
m_high.value = m_accum;
// Update the display with the value in the accumulator, but
// then clear the accumulator in preparation for the next input
updateText();
m_accum = 0;
}
break;
// Special operations
case KEY_EQUAL: // Equal/Enter key
{
// Is there a high precedence operation?
if (m_high.operation != (uint8_t)KEY_NONE)
{
m_accum = evaluateBinaryOperation(m_high.operation, m_high.value, m_accum);
m_high.operation = (uint8_t)KEY_NONE;
m_high.value = 0;
}
// Is there a pending low precedence operation?
if (m_low.operation != (uint8_t)KEY_NONE)
{
m_accum = evaluateBinaryOperation(m_low.operation, m_low.value, m_accum);
m_low.operation = (uint8_t)KEY_NONE;
m_low.value = 0;
}
// Update the display with the value in the accumulator. Flag that
// this is a result meaning that (1) it can be used as an accumulator
// for the next operation, but new input values cannot be appended to it.
updateText();
result = true;
}
break;
case KEY_DECIMAL: // Decimal mode
{
if (m_hexMode)
{
m_hexMode = false;
labelKeypad();
updateText();
}
}
break;
case KEY_HEXADECIMAL: // Hexadecimal mode
{
if (!m_hexMode)
{
m_hexMode = true;
labelKeypad();
updateText();
}
}
break;
case KEY_MRECALL: // Recall from memory
{
m_accum = m_memory;
updateText();
}
break;
case KEY_MPLUS: // Add to memory
{
m_memory += m_accum;
}
break;
case KEY_MMINUS: // Subtract from memory
{
m_memory -= m_accum;
}
break;
case KEY_MCLR: // Clear memory
{
m_memory = 0;
}
break;
case KEY_CLRENTRY: // Clear entry
{
m_accum = 0;
updateText();
}
break;
case KEY_CLR: // Clear all
{
m_accum = 0;
m_high.operation = (uint8_t)KEY_NONE;
m_high.value = 0;
m_low.operation = (uint8_t)KEY_NONE;
m_low.value = 0;
updateText();
}
break;
case KEY_NONE:
default:
gerr("ERROR: Invalid key type %d\n", g_keyDesc[index].keyType);
break;
}
// Remember if the accumulator contains a special reault
m_result = result;
}
}