|
@@ -0,0 +1,204 @@
|
|
|
+# --- Material UI calculator --- #
|
|
|
+import
|
|
|
+ strutils,
|
|
|
+ nodesnim
|
|
|
+
|
|
|
+
|
|
|
+type
|
|
|
+ TokenType {.size: sizeof(int8).} = enum
|
|
|
+ NUMBER,
|
|
|
+ OPERATOR,
|
|
|
+ RPAR,
|
|
|
+ LPAR
|
|
|
+ Token = ref object
|
|
|
+ token_type: TokenType
|
|
|
+ token_value: string
|
|
|
+ TokenTree = seq[Token]
|
|
|
+
|
|
|
+proc parseQuery(query: string): TokenTree =
|
|
|
+ result = @[]
|
|
|
+ for c in query:
|
|
|
+ if c.isDigit() or c == '.':
|
|
|
+ if result.len > 0 and not result[^1].isNil() and result[^1].token_type == NUMBER:
|
|
|
+ result[^1].token_value &= $c
|
|
|
+ else:
|
|
|
+ result.add(Token(token_type: NUMBER, token_value: $c))
|
|
|
+ elif c in "+-/*":
|
|
|
+ result.add(Token(token_type: OPERATOR, token_value: $c))
|
|
|
+ when false:
|
|
|
+ for i in result:
|
|
|
+ echo i.token_value
|
|
|
+
|
|
|
+proc findHigh(tree: TokenTree): int =
|
|
|
+ result = -1
|
|
|
+ let tokens = "/*-+"
|
|
|
+ for token in tokens:
|
|
|
+ for i in tree.low..tree.high:
|
|
|
+ if tree[i].token_type == OPERATOR and tree[i].token_value == $token:
|
|
|
+ return i-1
|
|
|
+
|
|
|
+
|
|
|
+proc calculate(tree: TokenTree): float =
|
|
|
+ result = 0f
|
|
|
+
|
|
|
+ var
|
|
|
+ t = tree
|
|
|
+ index = t.findHigh()
|
|
|
+
|
|
|
+ while index != -1:
|
|
|
+ case t[index+1].token_value
|
|
|
+ of "/":
|
|
|
+ t[index].token_value = $(t[index].token_value.parseFloat() / t[index+2].token_value.parseFloat())
|
|
|
+ of "*":
|
|
|
+ t[index].token_value = $(t[index].token_value.parseFloat() * t[index+2].token_value.parseFloat())
|
|
|
+ of "-":
|
|
|
+ t[index].token_value = $(t[index].token_value.parseFloat() - t[index+2].token_value.parseFloat())
|
|
|
+ of "+":
|
|
|
+ t[index].token_value = $(t[index].token_value.parseFloat() + t[index+2].token_value.parseFloat())
|
|
|
+ t.del(index+2)
|
|
|
+ t.del(index+1)
|
|
|
+ index = t.findHigh()
|
|
|
+ if t.len == 1:
|
|
|
+ result = parseFloat(t[0].token_value)
|
|
|
+
|
|
|
+Window("material ui calculator", ((64+32)*4)+16, 480)
|
|
|
+env.setBackgroundColor(Color("#FAFAFA"))
|
|
|
+
|
|
|
+
|
|
|
+var
|
|
|
+ query: string = ""
|
|
|
+ big_font = loadFont(standard_font_path, 32)
|
|
|
+ medium = loadFont(standard_font_path, 24)
|
|
|
+ small = loadFont(standard_font_path, 16)
|
|
|
+
|
|
|
+build:
|
|
|
+ - Button number_button:
|
|
|
+ call setStyle(style({color: "#EEEEEE"}))
|
|
|
+ call resize(64+32, 64)
|
|
|
+ call setTextFont(loadFont(standard_font_path, 24))
|
|
|
+ - Button operator_button:
|
|
|
+ call setStyle(style({color: "#F5F5F5"}))
|
|
|
+ call resize(64+32, 51.2f)
|
|
|
+ call setTextFont(loadFont(standard_font_path, 22))
|
|
|
+
|
|
|
+number_button.normal_background.setStyle(style({background-color: "#424242"}))
|
|
|
+number_button.hover_background.setStyle(style({background-color: "#616161"}))
|
|
|
+number_button.press_background.setStyle(style({background-color: "#757575"}))
|
|
|
+
|
|
|
+operator_button.normal_background.setStyle(style({background-color: "#616161"}))
|
|
|
+operator_button.hover_background.setStyle(style({background-color: "#757575"}))
|
|
|
+operator_button.press_background.setStyle(style({background-color: "#9E9E9E"}))
|
|
|
+
|
|
|
+
|
|
|
+when false:
|
|
|
+ query = "123+1*5-200/10"
|
|
|
+ var
|
|
|
+ parsed = parseQuery(query)
|
|
|
+ calculated = calculate(parsed)
|
|
|
+
|
|
|
+
|
|
|
+build:
|
|
|
+ - Scene main:
|
|
|
+ - HBox hbox:
|
|
|
+ separator: 0
|
|
|
+ call setPadding(8, 8, 8, 8)
|
|
|
+ call move(0, 200)
|
|
|
+ - GridBox numbers:
|
|
|
+ separator: 0
|
|
|
+ call setRow(3)
|
|
|
+ - Vbox operators:
|
|
|
+ separator: 0
|
|
|
+ - Control result_back:
|
|
|
+ call resize(((64+32)*4), 200)
|
|
|
+ call move(8, 8)
|
|
|
+ call setStyle(style({
|
|
|
+ background-color: "#4DD0E1",
|
|
|
+ shadow: true,
|
|
|
+ shadow-offset: "0 8"
|
|
|
+ }))
|
|
|
+ - Label text:
|
|
|
+ call setTextFont(loadFont(standard_font_path, 32))
|
|
|
+ call setTextColor(Color("#fff"))
|
|
|
+ call setTextAlign(1, 1, 1, 1)
|
|
|
+ call setAnchor(1, 1, 1, 1)
|
|
|
+ call setSizeAnchor(1, 0.5)
|
|
|
+ call setPadding(16, 16, 16, 16)
|
|
|
+
|
|
|
+
|
|
|
+for i in 0..11:
|
|
|
+ numbers.addChild(number_button.duplicate())
|
|
|
+ if i < 9:
|
|
|
+ numbers.getChild(i).ButtonRef.setText($(i+1))
|
|
|
+ numbers.getChild(i).ButtonRef@onClick(self, x, y):
|
|
|
+ query &= self.ButtonRef.getText()
|
|
|
+ text.setText(query)
|
|
|
+ elif i == 9:
|
|
|
+ numbers.getChild(i).ButtonRef.setText(".")
|
|
|
+ numbers.getChild(i).ButtonRef@onClick(self, x, y):
|
|
|
+ if query.len > 0 and query[^1] != '.':
|
|
|
+ query &= self.ButtonRef.getText()
|
|
|
+ text.setText(query)
|
|
|
+ elif i == 10:
|
|
|
+ numbers.getChild(i).ButtonRef.setText("0")
|
|
|
+ numbers.getChild(i).ButtonRef@onClick(self, x, y):
|
|
|
+ if query.len > 0:
|
|
|
+ query &= self.ButtonRef.getText()
|
|
|
+ text.setText(query)
|
|
|
+ elif i == 11:
|
|
|
+ numbers.getChild(i).ButtonRef.setText("=")
|
|
|
+ numbers.getChild(i).ButtonRef@onClick(self, x, y):
|
|
|
+ if query.len > 0 and query[^1] in "/*-+":
|
|
|
+ query = "0"
|
|
|
+ var calculated = parseQuery(query).calculate()
|
|
|
+ query = $calculated
|
|
|
+ text.setText(query)
|
|
|
+
|
|
|
+for i in 0..4:
|
|
|
+ operators.addChild(operator_button.duplicate())
|
|
|
+ case i
|
|
|
+ of 0:
|
|
|
+ operators.getChild(i).ButtonRef.setText("DEL")
|
|
|
+ operators.getChild(i).ButtonRef@onClick(self, x, y):
|
|
|
+ if query.len > 0:
|
|
|
+ query = query[0..^2]
|
|
|
+ text.setText(query)
|
|
|
+ of 1:
|
|
|
+ operators.getChild(i).ButtonRef.setText("+")
|
|
|
+ operators.getChild(i).ButtonRef@onClick(self, x, y):
|
|
|
+ if query.len > 0:
|
|
|
+ if query[^1] notin "-+/*":
|
|
|
+ query &= "+"
|
|
|
+ else:
|
|
|
+ query = query[0..^2] & "+"
|
|
|
+ text.setText(query)
|
|
|
+ of 2:
|
|
|
+ operators.getChild(i).ButtonRef.setText("−")
|
|
|
+ operators.getChild(i).ButtonRef@onClick(self, x, y):
|
|
|
+ if query.len > 0:
|
|
|
+ if query[^1] notin "-+/*":
|
|
|
+ query &= "-"
|
|
|
+ else:
|
|
|
+ query = query[0..^2] & "-"
|
|
|
+ text.setText(query)
|
|
|
+ of 3:
|
|
|
+ operators.getChild(i).ButtonRef.setText("÷")
|
|
|
+ operators.getChild(i).ButtonRef@onClick(self, x, y):
|
|
|
+ if query.len > 0:
|
|
|
+ if query[^1] notin "-+/*":
|
|
|
+ query &= "/"
|
|
|
+ else:
|
|
|
+ query = query[0..^2] & "/"
|
|
|
+ text.setText(query)
|
|
|
+ else:
|
|
|
+ operators.getChild(i).ButtonRef.setText("×")
|
|
|
+ operators.getChild(i).ButtonRef@onClick(self, x, y):
|
|
|
+ if query.len > 0:
|
|
|
+ if query[^1] notin "-+/*":
|
|
|
+ query &= "*"
|
|
|
+ else:
|
|
|
+ query = query[0..^2] & "*"
|
|
|
+ text.setText(query)
|
|
|
+
|
|
|
+
|
|
|
+addMainScene(main)
|
|
|
+windowLaunch()
|