calculator_app.lua 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. laptop.register_app("calculator", {
  2. app_name = "Calculator",
  3. app_icon = "laptop_calculator.png",
  4. app_info = "Perform Mathematical Calculations",
  5. formspec_func = function(app, mtos)
  6. local data = mtos.bdev:get_app_storage('ram', 'calculator')
  7. if not data.tab then
  8. data.tab = {}
  9. end
  10. if not data.tab[1] then
  11. table.insert(data.tab, {})
  12. end
  13. local formspec = mtos.theme:get_tableoptions(false).."tablecolumns[" ..
  14. "text,align=right,padding=1.5,width=10;".. -- first value
  15. "text,align=right,padding=1.5;".. -- operator
  16. "text,align=right,padding=1.5,width=10]".. -- last value
  17. "table[3.9,0.8;7,2;tab;"
  18. for idx,entry in ipairs(data.tab) do
  19. if idx > 1 then
  20. formspec = formspec..','
  21. end
  22. formspec = formspec..(entry.var1 or "")..","..(entry.operator or "")..","..(entry.var2 or "")
  23. end
  24. formspec = formspec .. ";"..#data.tab.."]"..
  25. mtos.theme:get_button('4,3;1,1', "minor", 'number', '1') ..
  26. mtos.theme:get_button('5,3;1,1', "minor", 'number', '2') ..
  27. mtos.theme:get_button('6,3;1,1', "minor", 'number', '3') ..
  28. mtos.theme:get_button('4,4;1,1', "minor", 'number', '4') ..
  29. mtos.theme:get_button('5,4;1,1', "minor", 'number', '5') ..
  30. mtos.theme:get_button('6,4;1,1', "minor", 'number', '6') ..
  31. mtos.theme:get_button('4,5;1,1', "minor", 'number', '7') ..
  32. mtos.theme:get_button('5,5;1,1', "minor", 'number', '8') ..
  33. mtos.theme:get_button('6,5;1,1', "minor", 'number', '9') ..
  34. mtos.theme:get_button('4,6;1,1', "minor", 'number', '0') ..
  35. mtos.theme:get_button('5,6;1,1', "minor", 'number', '.') ..
  36. mtos.theme:get_button('6,6;1,1', "minor", 'minus', '+/-') ..
  37. mtos.theme:get_button('4,7;1,1',"minor", 'constant_pi', "PI")..
  38. mtos.theme:get_button('5,7;1,1', "minor", 'constant_e', "e")..
  39. mtos.theme:get_button('6,7;1,1', "minor", 'rnd', "RND")..
  40. mtos.theme:get_button('8,3;1,1', "minor", 'operator', '+') ..
  41. mtos.theme:get_button('8,4;1,1', "minor", 'operator', '-') ..
  42. mtos.theme:get_button('8,5;1,1', "minor", 'operator', '/') ..
  43. mtos.theme:get_button('8,6;1,1', "minor", 'operator', '*') ..
  44. mtos.theme:get_button('8,7;1,1', "minor", 'operator', '^') ..
  45. mtos.theme:get_button('9,6;2,1', "minor", 'operator', '=') ..
  46. mtos.theme:get_button('9,3;2,1', "minor", 'del_char', 'DEL-1') ..
  47. mtos.theme:get_button('9,4;2,1', "minor", 'del_line', 'DEL-L') ..
  48. mtos.theme:get_button('9,5;2,1', "minor", 'del_all', 'DEL-A')
  49. return formspec
  50. end,
  51. receive_fields_func = function(app, mtos, sender, fields)
  52. local data = mtos.bdev:get_app_storage('ram', 'calculator')
  53. local entry = data.tab[#data.tab]
  54. if fields.number then
  55. -- simple number entry. With check for valid value
  56. local new_val = (entry.var2 or "")..minetest.strip_colors(fields.number)
  57. if tonumber(new_val) then
  58. entry.var2 = new_val
  59. end
  60. elseif fields.minus then
  61. if entry.var2 then
  62. entry.var2 = tostring(-tonumber(entry.var2))
  63. else
  64. entry.var2 = '-0'
  65. end
  66. elseif fields.constant_pi then
  67. entry.var2 = tostring(math.pi)
  68. elseif fields.constant_e then
  69. entry.var2 = tostring(math.exp(1))
  70. elseif fields.rnd then
  71. entry.var2 = tostring(math.random())
  72. elseif fields.del_char then
  73. -- delete char
  74. if entry.var2 then
  75. -- remove char from current number
  76. entry.var2 = entry.var2:sub(1, -2)
  77. if not tonumber(entry.var2) then
  78. entry.var2 = nil
  79. end
  80. else
  81. -- get previous number
  82. if #data.tab > 1 then
  83. -- go back to previous line if exists
  84. table.remove(data.tab, #data.tab)
  85. else
  86. -- get from left site if first entry
  87. entry.var2 = entry.var1
  88. entry.operator = nil
  89. entry.var1 = nil
  90. end
  91. end
  92. elseif fields.del_line then
  93. -- just delete full number if exists
  94. if entry.var2 then
  95. entry.var2 = nil
  96. else
  97. -- go back to previous line and delete the full number if exists
  98. table.remove(data.tab, #data.tab)
  99. if #data.tab > 0 then
  100. entry = data.tab[#data.tab]
  101. entry.var2 = nil
  102. end
  103. end
  104. elseif fields.del_all then
  105. data.tab = nil
  106. elseif fields.operator then
  107. fields.operator = minetest.strip_colors(fields.operator)
  108. -- no previous operator
  109. if not entry.operator then
  110. if fields.operator == '=' and (entry.var1 or entry.var2) then
  111. table.insert(data.tab, {}) -- add empty line
  112. elseif entry.var2 then
  113. -- move to the left
  114. entry.var1 = entry.var2
  115. entry.operator = fields.operator
  116. entry.var2 = nil
  117. end
  118. -- process previous operator
  119. else
  120. local result
  121. if entry.var2 then
  122. -- both values available
  123. if entry.operator == '+' then
  124. result = tonumber(entry.var1) + tonumber(entry.var2)
  125. elseif entry.operator == '-' then
  126. result = tonumber(entry.var1) - tonumber(entry.var2)
  127. elseif entry.operator == '/' then
  128. result = tonumber(entry.var1) / tonumber(entry.var2)
  129. elseif entry.operator == '*' then
  130. result = tonumber(entry.var1) * tonumber(entry.var2)
  131. elseif entry.operator == '^' then
  132. result = tonumber(entry.var1) ^ tonumber(entry.var2)
  133. elseif entry.operator == '=' then
  134. result = tonumber(entry.var2)
  135. end
  136. else
  137. if entry.operator == '-' then
  138. result = - tonumber(entry.var1)
  139. end
  140. end
  141. if result then
  142. if fields.operator == '=' then
  143. table.insert(data.tab, {var2 = tostring(result)})
  144. else
  145. table.insert(data.tab, {var1 = tostring(result), operator = fields.operator})
  146. end
  147. end
  148. end
  149. end
  150. end
  151. })