material_ui.nim 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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.background_color = 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:
  65. setStyle(style({color: "#EEEEEE"}))
  66. resize(64+32, 64)
  67. setTextFont(loadFont(standard_font_path, 24))
  68. - Button operator_button:
  69. call:
  70. setStyle(style({color: "#F5F5F5"}))
  71. resize(64+32, 51.2f)
  72. setTextFont(loadFont(standard_font_path, 22))
  73. number_button.normal_background.setStyle(style({background-color: "#424242"}))
  74. number_button.hover_background.setStyle(style({background-color: "#616161"}))
  75. number_button.press_background.setStyle(style({background-color: "#757575"}))
  76. operator_button.normal_background.setStyle(style({background-color: "#616161"}))
  77. operator_button.hover_background.setStyle(style({background-color: "#757575"}))
  78. operator_button.press_background.setStyle(style({background-color: "#9E9E9E"}))
  79. when false:
  80. query = "123+1*5-200/10"
  81. var
  82. parsed = parseQuery(query)
  83. calculated = calculate(parsed)
  84. build:
  85. - Scene main:
  86. - HBox hbox:
  87. separator: 0
  88. call:
  89. setPadding(8, 8, 8, 8)
  90. move(0, 200)
  91. - GridBox numbers:
  92. separator: 0
  93. call setRow(3)
  94. - Vbox operators:
  95. separator: 0
  96. - Control result_back:
  97. call:
  98. resize(((64+32)*4), 200)
  99. move(8, 8)
  100. setStyle(style({
  101. background-color: "#4DD0E1",
  102. shadow: true,
  103. shadow-offset: "0 8"
  104. }))
  105. - Label text:
  106. call:
  107. setTextFont(loadFont(standard_font_path, 32))
  108. setTextColor(Color("#fff"))
  109. setTextAlign(1, 1, 1, 1)
  110. setAnchor(1, 1, 1, 1)
  111. setSizeAnchor(1, 0.5)
  112. setPadding(16, 16, 16, 16)
  113. for i in 0..11:
  114. numbers.addChild(number_button.duplicate())
  115. if i < 9:
  116. numbers.getChild(i).ButtonRef.setText($(i+1))
  117. numbers.getChild(i).ButtonRef@onClick(self, x, y):
  118. query &= self.ButtonRef.getText()
  119. text.setText(query)
  120. elif i == 9:
  121. numbers.getChild(i).ButtonRef.setText(".")
  122. numbers.getChild(i).ButtonRef@onClick(self, x, y):
  123. if query.len > 0 and query[^1] != '.':
  124. query &= self.ButtonRef.getText()
  125. text.setText(query)
  126. elif i == 10:
  127. numbers.getChild(i).ButtonRef.setText("0")
  128. numbers.getChild(i).ButtonRef@onClick(self, x, y):
  129. if query.len > 0:
  130. query &= self.ButtonRef.getText()
  131. text.setText(query)
  132. elif i == 11:
  133. numbers.getChild(i).ButtonRef.setText("=")
  134. numbers.getChild(i).ButtonRef@onClick(self, x, y):
  135. if query.len > 0 and query[^1] in "/*-+":
  136. query = "0"
  137. var calculated = parseQuery(query).calculate()
  138. query = $calculated
  139. text.setText(query)
  140. for i in 0..4:
  141. operators.addChild(operator_button.duplicate())
  142. case i
  143. of 0:
  144. operators.getChild(i).ButtonRef.setText("DEL")
  145. operators.getChild(i).ButtonRef@onClick(self, x, y):
  146. if query.len > 0:
  147. query = query[0..^2]
  148. text.setText(query)
  149. of 1:
  150. operators.getChild(i).ButtonRef.setText("+")
  151. operators.getChild(i).ButtonRef@onClick(self, x, y):
  152. if query.len > 0:
  153. if query[^1] notin "-+/*":
  154. query &= "+"
  155. else:
  156. query = query[0..^2] & "+"
  157. text.setText(query)
  158. of 2:
  159. operators.getChild(i).ButtonRef.setText("−")
  160. operators.getChild(i).ButtonRef@onClick(self, x, y):
  161. if query.len > 0:
  162. if query[^1] notin "-+/*":
  163. query &= "-"
  164. else:
  165. query = query[0..^2] & "-"
  166. text.setText(query)
  167. of 3:
  168. operators.getChild(i).ButtonRef.setText("÷")
  169. operators.getChild(i).ButtonRef@onClick(self, x, y):
  170. if query.len > 0:
  171. if query[^1] notin "-+/*":
  172. query &= "/"
  173. else:
  174. query = query[0..^2] & "/"
  175. text.setText(query)
  176. else:
  177. operators.getChild(i).ButtonRef.setText("×")
  178. operators.getChild(i).ButtonRef@onClick(self, x, y):
  179. if query.len > 0:
  180. if query[^1] notin "-+/*":
  181. query &= "*"
  182. else:
  183. query = query[0..^2] & "*"
  184. text.setText(query)
  185. addMainScene(main)
  186. windowLaunch()