Module:Calculator widget
Appearance
Creates an interactive 4-function calculator widget (See right). Requires the calculator gadget to work.
Usage
{{#invoke:Calculator widget|getWidget}}
Optional parameter fallback to determine what to do for users without javascript (or calculator gadget enabled). Default "all" to show full thing, "keypad" to show only keypad and "none" to make calculator invisible
local p = {}
-- Make a calculator widget using {{calculator}}
local function getDisplay()
return 'ifzero(displayY,x,y)'
end
local function pressDecimal()
return {
{'decimal', 'ifequal(decimal,0,1,decimal)'},
{ 'y', 'ifzero(equalFlag,y,0)' },
{ 'x', 'ifzero(displayY,x,0)' },
{ 'equalFlag', 0 },
{ 'displayY', '0' }
}
end
-- This is sketch because x should happen before decimal.
function pressNumber(n)
return { {'x', 'ifequal(decimal,0,not(displayY)*x*10+(ifpositive(not(displayY)*x,1,-1))*' .. n .. ','
.. 'x+(ifpositive(x,1,-1))*(' .. n .. '/pow(10,decimal)))'},
{'decimal','ifzero(decimal,0,decimal+1)'},
{ 'y', 'ifzero(equalFlag,y,0)' },
{ 'op', 'ifzero(equalFlag,op,0)' },
{ 'equalFlag', 0 },
{ 'displayY', '0' },
}
end
function getClear()
return {
{ 'x', '0' },
{ 'y', '0' },
{ 'op', '0' },
{ 'decimal', '0' },
{ 'percentFlag', '0' },
{ 'equalFlag', '0' },
{ 'displayY', '0' },
}
end
function compute(op)
local res = {
{ 'x', 'ifequal(percentFlag, 1, x*y/100, x)' },
{ 'y', 'switch(op,0,x+y,1,y-x,2,x*y,3,y/x)' },
--{ 'x', '0' },
{ 'decimal', '0' },
{ 'displayY', '1' },
{ 'percentFlag', 0 },
{ 'op', tostring(op) }
}
-- After pressing equal, you can either type a new number
-- or continue using the current value by pressing an operator.
if op == 'op' then
res[#res+1] = { 'equalFlag', '1' }
else
res[#res+1] = { 'equalFlag', 0 }
end
return res
end
function p.getWidget( frame )
local buttons = {
{ "MC", {{"mem", "0"}} },
{ "MR", {{"x", "mem"},{"displayY", 0}} },
{ "M−", {{"mem", "ifzero(displayY,mem-x,mem-y)"}} },
{ "M+", {{"mem", "ifzero(displayY,mem+x,mem+y)"}} },
{ "C", getClear() },
{ "±", {{'x', '0-x'}} },
{ "%", {{'percentFlag', '1'}} },
{ "√", {{'x','sqrt(x)'}} },
{ "7", pressNumber(7) },
{ "8", pressNumber(8) },
{ "9", pressNumber(9) },
{ "÷", compute(3) },
{ "4", pressNumber(4) },
{ "5", pressNumber(5) },
{ "6", pressNumber(6) },
{ "×", compute(2) },
{ "1", pressNumber(1) },
{ "2", pressNumber(2) },
{ "3", pressNumber(3) },
{ "−", compute(1) },
{ "0", pressNumber(0) },
{ ".", pressDecimal() },
{ "=", compute('op') },
{ "+", compute(0) },
}
local calc = '<div class="calculatorwidget calculator-container" style="display:grid;grid-template-columns:repeat(4, 1fr);grid-gap:5px;min-width:256px;width:20ch;border:thin solid gray;padding: 5px; background: #eee">'
-- On Calculator page, we want to show the layout of buttons on print, but
-- not the answer field.
.. '<div style="grid-column:1/5;display:none" class="calculatorgadget-enabled">{{Calculator codex text|default=0|id=ans|formula=' .. getDisplay() .. '|style=text-align:right;font-weight:bold;|readonly=1|NaN-text=Error}}</div>'
for i, v in ipairs(buttons) do
local calcType, calcWeight
if v[1] == 'C' then
calcType = 'destructive'
calcWeight = 'normal'
elseif v[1] == '=' then
calcType = 'progressive'
calcWeight = 'primary'
else
calcType = 'default'
calcWeight = 'normal'
end
-- maybe make "=" be progressive instead of default. Perhaps weight = primary?
local forVar = ''
local formula = ''
for i2, v2 in ipairs( v[2] ) do
forVar = forVar .. ';' .. v2[1]
formula = formula .. ';' .. v2[2]
end
calc = calc .. '{{calculator button|type='.. calcType ..'|weight='.. calcWeight .. '|for=' .. string.sub(forVar,2) .. '|formula=' .. string.sub(formula,2) .. '|contents='.. v[1] .. '}}'
end
calc = calc .. '{{calculator|type=hidden|id=x|default=0}}'
calc = calc .. '{{calculator|type=hidden|id=y|default=0}}'
calc = calc .. '{{calculator|type=hidden|id=mem|default=0}}'
calc = calc .. '{{calculator|type=hidden|id=op|default=0}}'
calc = calc .. '{{calculator|type=hidden|id=decimal|default=0}}'
calc = calc .. '{{calculator|type=hidden|id=displayY|default=0}}'
calc = calc .. '{{calculator|type=hidden|id=percentFlag|default=0}}'
calc = calc .. '{{calculator|type=hidden|id=equalFlag|default=0}}'
calc = calc .. '</div>'
return frame:preprocess(calc)
end
return p