material_ui.nim 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. # --- Material UI calculator --- #
  2. import
  3. strutils,
  4. nodesnim
  5. type
  6. TokenType {.size: sizeof(int8).} = enum
  7. NUMBER,
  8. OPERATOR,
  9. RPAR,
  10. LPAR
  11. Token = ref object
  12. token_type: TokenType
  13. token_value: string
  14. TokenTree = seq[Token]
  15. proc parseQuery(query: string): TokenTree =
  16. result = @[]
  17. for c in query:
  18. if c.isDigit() or c == '.':
  19. if result.len > 0 and not result[^1].isNil() and result[^1].token_type == NUMBER:
  20. result[^1].token_value &= $c
  21. else:
  22. result.add(Token(token_type: NUMBER, token_value: $c))
  23. elif c in "+-/*":
  24. result.add(Token(token_type: OPERATOR, token_value: $c))
  25. when false:
  26. for i in result:
  27. echo i.token_value
  28. proc findHigh(tree: TokenTree): int =
  29. result = -1
  30. let tokens = "/*-+"
  31. for token in tokens:
  32. for i in tree.low..tree.high:
  33. if tree[i].token_type == OPERATOR and tree[i].token_value == $token:
  34. return i-1
  35. proc calculate(tree: TokenTree): float =
  36. result = 0f
  37. var
  38. t = tree
  39. index = t.findHigh()
  40. while index != -1:
  41. case t[index+1].token_value
  42. of "/":
  43. t[index].token_value = $(t[index].token_value.parseFloat() / t[index+2].token_value.parseFloat())
  44. of "*":
  45. t[index].token_value = $(t[index].token_value.parseFloat() * t[index+2].token_value.parseFloat())
  46. of "-":
  47. t[index].token_value = $(t[index].token_value.parseFloat() - t[index+2].token_value.parseFloat())
  48. of "+":
  49. t[index].token_value = $(t[index].token_value.parseFloat() + t[index+2].token_value.parseFloat())
  50. t.del(index+2)
  51. t.del(index+1)
  52. index = t.findHigh()
  53. if t.len == 1:
  54. result = parseFloat(t[0].token_value)
  55. Window("material ui calculator", ((64+32)*4)+16, 480)
  56. env.setBackgroundColor(Color("#FAFAFA"))
  57. var
  58. query: string = ""
  59. big_font = loadFont(standard_font_path, 32)
  60. medium = loadFont(standard_font_path, 24)
  61. small = loadFont(standard_font_path, 16)
  62. build:
  63. - Button number_button:
  64. call setStyle(style({color: "#EEEEEE"}))
  65. call resize(64+32, 64)
  66. call setTextFont(loadFont(standard_font_path, 24))
  67. - Button operator_button:
  68. call setStyle(style({color: "#F5F5F5"}))
  69. call resize(64+32, 51.2f)
  70. call setTextFont(loadFont(standard_font_path, 22))
  71. number_button.normal_background.setStyle(style({background-color: "#424242"}))
  72. number_button.hover_background.setStyle(style({background-color: "#616161"}))
  73. number_button.press_background.setStyle(style({background-color: "#757575"}))
  74. operator_button.normal_background.setStyle(style({background-color: "#616161"}))
  75. operator_button.hover_background.setStyle(style({background-color: "#757575"}))
  76. operator_button.press_background.setStyle(style({background-color: "#9E9E9E"}))
  77. when false:
  78. query = "123+1*5-200/10"
  79. var
  80. parsed = parseQuery(query)
  81. calculated = calculate(parsed)
  82. build:
  83. - Scene main:
  84. - HBox hbox:
  85. separator: 0
  86. call setPadding(8, 8, 8, 8)
  87. call move(0, 200)
  88. - GridBox numbers:
  89. separator: 0
  90. call setRow(3)
  91. - Vbox operators:
  92. separator: 0
  93. - Control result_back:
  94. call resize(((64+32)*4), 200)
  95. call move(8, 8)
  96. call setStyle(style({
  97. background-color: "#4DD0E1",
  98. shadow: true,
  99. shadow-offset: "0 8"
  100. }))
  101. - Label text:
  102. call setTextFont(loadFont(standard_font_path, 32))
  103. call setTextColor(Color("#fff"))
  104. call setTextAlign(1, 1, 1, 1)
  105. call setAnchor(1, 1, 1, 1)
  106. call setSizeAnchor(1, 0.5)
  107. call setPadding(16, 16, 16, 16)
  108. for i in 0..11:
  109. numbers.addChild(number_button.duplicate())
  110. if i < 9:
  111. numbers.getChild(i).ButtonRef.setText($(i+1))
  112. numbers.getChild(i).ButtonRef@onClick(self, x, y):
  113. query &= self.ButtonRef.getText()
  114. text.setText(query)
  115. elif i == 9:
  116. numbers.getChild(i).ButtonRef.setText(".")
  117. numbers.getChild(i).ButtonRef@onClick(self, x, y):
  118. if query.len > 0 and query[^1] != '.':
  119. query &= self.ButtonRef.getText()
  120. text.setText(query)
  121. elif i == 10:
  122. numbers.getChild(i).ButtonRef.setText("0")
  123. numbers.getChild(i).ButtonRef@onClick(self, x, y):
  124. if query.len > 0:
  125. query &= self.ButtonRef.getText()
  126. text.setText(query)
  127. elif i == 11:
  128. numbers.getChild(i).ButtonRef.setText("=")
  129. numbers.getChild(i).ButtonRef@onClick(self, x, y):
  130. if query.len > 0 and query[^1] in "/*-+":
  131. query = "0"
  132. var calculated = parseQuery(query).calculate()
  133. query = $calculated
  134. text.setText(query)
  135. for i in 0..4:
  136. operators.addChild(operator_button.duplicate())
  137. case i
  138. of 0:
  139. operators.getChild(i).ButtonRef.setText("DEL")
  140. operators.getChild(i).ButtonRef@onClick(self, x, y):
  141. if query.len > 0:
  142. query = query[0..^2]
  143. text.setText(query)
  144. of 1:
  145. operators.getChild(i).ButtonRef.setText("+")
  146. operators.getChild(i).ButtonRef@onClick(self, x, y):
  147. if query.len > 0:
  148. if query[^1] notin "-+/*":
  149. query &= "+"
  150. else:
  151. query = query[0..^2] & "+"
  152. text.setText(query)
  153. of 2:
  154. operators.getChild(i).ButtonRef.setText("−")
  155. operators.getChild(i).ButtonRef@onClick(self, x, y):
  156. if query.len > 0:
  157. if query[^1] notin "-+/*":
  158. query &= "-"
  159. else:
  160. query = query[0..^2] & "-"
  161. text.setText(query)
  162. of 3:
  163. operators.getChild(i).ButtonRef.setText("÷")
  164. operators.getChild(i).ButtonRef@onClick(self, x, y):
  165. if query.len > 0:
  166. if query[^1] notin "-+/*":
  167. query &= "/"
  168. else:
  169. query = query[0..^2] & "/"
  170. text.setText(query)
  171. else:
  172. operators.getChild(i).ButtonRef.setText("×")
  173. operators.getChild(i).ButtonRef@onClick(self, x, y):
  174. if query.len > 0:
  175. if query[^1] notin "-+/*":
  176. query &= "*"
  177. else:
  178. query = query[0..^2] & "*"
  179. text.setText(query)
  180. addMainScene(main)
  181. windowLaunch()