diff --git a/__main__.py b/__main__.py index 3841e01..ea1e29f 100644 --- a/__main__.py +++ b/__main__.py @@ -17,39 +17,63 @@ class Window(CTk): self.attributes("-fullscreen", True) # Initialize screen as fullscreen self.bind("", self.quitApplication) # quit application - self.amountDue: float = 0.0 - - self.left_frame: CTkFrame = CTkFrame(master=self, width=(self.width / 2 - 20), height=(self.height / 2 - 40), fg_color="gray20") + # Left frame top half + self.left_frame: CTkFrame = CTkFrame( + master=self, + width=(self.width / 2 - 20), + height=(self.height / 2 - 40), + fg_color="gray20" + ) self.left_frame.grid_propagate(False) self.left_frame.grid(row=0, column=0, pady=20, padx=10, sticky='NW') # Static label - mainLabel: CTkLabel = CTkLabel(master=self.left_frame, text="Change Due Calculator", font=("Arial", 18, 'bold')) + mainLabel: CTkLabel = CTkLabel( + master=self.left_frame, + text="Change Due Calculator", + font=("Arial", 18, 'bold') + ) mainLabel.grid(row=0, column=0, pady=12) - calculateFrame: CTkFrame = CTkFrame(master=self.left_frame, width=((self.width / 2 - 20) / 2), height=(self.height / 2 - 110), fg_color="gray15") + # Calculator frame + calcFrameWidth: int = (self.width / 2 - 20) / 2 - 15 + calculateFrame: CTkFrame = CTkFrame( + master=self.left_frame, + width=calcFrameWidth, + height=(self.height / 2 - 110), + fg_color="gray15" + ) calculateFrame.grid_propagate(False) - calculateFrame.grid(pady=(0, 12), padx=15) + calculateFrame.grid(pady=(0, 12), padx=(15, 0)) self.amount = StringVar() self.amountBox: CTkEntry = CTkEntry( master=calculateFrame, - width=(((self.width / 2 - 20) / 2) - 24), + width=(calcFrameWidth - 20), height=50, - textvariable=self.amount + textvariable=self.amount, + justify='right', + font=("Arial", 24, 'bold'), ) + self.amountBox.configure(state="disabled") self.amountBox.grid(row=0, column=0, pady=12, padx=10) - calculateButtonFrame: CTkFrame = CTkFrame(master=calculateFrame, width=(((self.width / 2 - 20) / 2) - 24), height=(self.height / 2 - 196), fg_color="gray15") + # Calculator buttons frame + calculateButtonFrame: CTkFrame = CTkFrame( + master=calculateFrame, + width=(calcFrameWidth - 20), + height=(self.height / 2 - 196), + fg_color="gray15" + ) calculateButtonFrame.grid_propagate(False) calculateButtonFrame.grid(row=1, column=0, pady=(0, 12), padx=10) buttons: list[CTkButton] = [CTkButton( master=calculateButtonFrame, - text=f'{i}', - command=lambda: self.amountSum(f'{i}'), - width=(((self.width / 2 - 20) / 2) - 48) / 3, + text=str(i), + width=(calcFrameWidth - 20) / 3 - 8, height=(self.height / 2 - 196) / 4 - 12, + font=("Arial", 24, 'bold'), ) for i in range(0, 10)] buttons[0].grid(row=3, column=1, padx=(0, 12), pady=(12, 0)) @@ -59,33 +83,111 @@ class Window(CTk): buttons[i].grid(row=r, column=c, padx=(0, 12), pady=(12, 0)) i += 1 - # Warning Label - self.invalidLabel: CTkLabel = CTkLabel(master=self.left_frame, text="Not a Number!", text_color="red", font=("Arial", 20, 'bold')) - - calculateButton: CTkButton = CTkButton(master=self.left_frame, text="Calculate", command=self.calculate, width=200, height=50) + # I have already tried multiple ways to define the command in either the + # buttons list comprehension or in the button layout loop, but the lambda + # function always passes 'i' as the last number (9) so all buttons have the + # value 9 passed to self.amountConcat + # So this is the solution >:( + buttons[0]._command = lambda: self.amountConcat('0') + buttons[1]._command = lambda: self.amountConcat('1') + buttons[2]._command = lambda: self.amountConcat('2') + buttons[3]._command = lambda: self.amountConcat('3') + buttons[4]._command = lambda: self.amountConcat('4') + buttons[5]._command = lambda: self.amountConcat('5') + buttons[6]._command = lambda: self.amountConcat('6') + buttons[7]._command = lambda: self.amountConcat('7') + buttons[8]._command = lambda: self.amountConcat('8') + buttons[9]._command = lambda: self.amountConcat('9') + + decimalButton: CTkButton = CTkButton( + master=calculateButtonFrame, + text='.', + command=lambda: self.amountConcat('.'), + width=(calcFrameWidth - 20) / 3 - 8, + height=(self.height / 2 - 196) / 4 - 12, + font=("Arial", 24, 'bold'), + ) + decimalButton.grid(row=3, column=0, padx=(0, 12), pady=(12, 0)) + + deleteButton: CTkButton = CTkButton( + master=calculateButtonFrame, + text='⌫', + command=lambda: self.amountConcat('⌫'), + width=(calcFrameWidth - 20) / 3 - 8, + height=(self.height / 2 - 196) / 4 - 12, + font=("Arial", 24, 'bold'), + ) + deleteButton.grid(row=3, column=2, padx=(0, 12), pady=(12, 0)) + + # General action buttons frame, (next to calculator frame) + actionFrame: CTkFrame = CTkFrame( + master=self.left_frame, + width=calcFrameWidth, + height=(self.height / 2 - 110), + fg_color="gray20" + ) + actionFrame.grid_propagate(False) + actionFrame.grid(row=1, column=1, pady=(0, 12), padx=(15, 0)) + + calculateButton: CTkButton = CTkButton( + master=actionFrame, + text="Calculate", + command=self.calculate, + width=200, height=50 + ) calculateButton.grid(row=1, column=2, pady=12, padx=10) - clearButton: CTkButton = CTkButton(master=self.left_frame, text="Clear", command=self.clear, width=200, height=50) + clearButton: CTkButton = CTkButton( + master=actionFrame, + text="Clear", + command=self.clear, + width=200, + height=50 + ) clearButton.grid(row=1, column=3, pady=12, padx=10) - self.left_frame_bottom: CTkFrame = CTkFrame(master=self, width=(self.width / 2 - 20), height=(self.height / 2 - 40), fg_color="gray20") + # Left frame bottom + self.left_frame_bottom: CTkFrame = CTkFrame( + master=self, + width=(self.width / 2 - 20), + height=(self.height / 2 - 40), + fg_color="gray20" + ) self.left_frame_bottom.grid_propagate(False) self.left_frame_bottom.grid(row=0, column=0, pady=20, padx=10, sticky='SW') - paidWithLabel: CTkLabel = CTkLabel(master=self.left_frame_bottom, text="Paid With", font=("Arial", 18, 'bold')) + paidWithLabel: CTkLabel = CTkLabel( + master=self.left_frame_bottom, + text="Paid With", + font=("Arial", 18, 'bold') + ) paidWithLabel.grid(row=0, column=0, pady=(16, 0), padx=10) + # Options self.mode: bool = True # True == ADD, False == SUBTRACT - self.modeLabel: CTkLabel = CTkLabel(master=self.left_frame_bottom, text=f"Mode: {'ADD' if self.mode else 'SUBTRACT'}", font=("Arial", 18, 'bold')) - self.modeLabel.grid(row=0, column=4, pady=(16, 0), padx=(50, 10), sticky='NE') + self.modeLabel: CTkLabel = CTkLabel( + master=self.left_frame_bottom, + text=f"Mode: {'ADD' if self.mode else 'SUBTRACT'}", + font=("Arial", 18, 'bold') + ) + self.modeLabel.grid(row=0, column=4, pady=(16, 0), padx=(50, 10)) - self.modeSelect: CTkSwitch = CTkSwitch(master=self.left_frame_bottom, text="Mode", command=self.updateMode) - self.modeSelect.grid(row=0, column=3, pady=(16, 0), padx=(50, 10), sticky='NE') + self.modeSelect: CTkSwitch = CTkSwitch( + master=self.left_frame_bottom, + text="Mode", + command=self.updateMode + ) + self.modeSelect.grid(row=0, column=3, pady=(16, 0), padx=(50, 10)) self.total: float = 0.0 - self.totalLabel: CTkLabel = CTkLabel(master=self.left_frame_bottom, text=f"Total: {self.total}", font=("Arial", 18, 'bold')) + self.totalLabel: CTkLabel = CTkLabel( + master=self.left_frame_bottom, + text=f"Total: {self.total}", + font=("Arial", 18, 'bold') + ) self.totalLabel.grid(row=0, column=2, pady=(16, 0), padx=10, sticky='NE') + # input Buttons currencyButtons: list[CTkButton] = initializeCurrencyButtons(self.left_frame_bottom, self.sum) r, c = 1, 0 @@ -94,7 +196,13 @@ class Window(CTk): if c < 3: c += 1 else: c = 0; r += 1 - self.right_frame: CTkFrame = CTkFrame(master=self, width=(self.width / 2 - 20), height=(self.height - 40), fg_color="gray20") + # Right frame for output + self.right_frame: CTkFrame = CTkFrame( + master=self, + width=(self.width / 2 - 20), + height=(self.height - 40), + fg_color="gray20" + ) self.right_frame.grid_propagate(False) self.right_frame.grid(row=0, column=1, pady=20, padx=10) @@ -107,7 +215,8 @@ class Window(CTk): def quitApplication(self, event=None) -> None: self.destroy() def calculate(self) -> None: - print(self.amountDue) + amountDue: float = float(self.amount.get()) + print(amountDue) def sum(self, value: float) -> None: if self.total == 0 and not self.mode: return @@ -115,11 +224,17 @@ class Window(CTk): if self.total < 0: self.total = 0 self.totalLabel.configure(text=f"Total: {self.total:.2f}") - def amountSum(self, value: str) -> None: - pass + def amountConcat(self, value: str) -> None: + current: str = self.amount.get() + if value == "⌫": current = current[:-1] + elif len(current) == 0 and value == "0": return + elif '.' in current and value == '.': return + elif '.' in current and len(current.split('.')[1]) == 2: return + else: current += value + self.amount.set(current) def clear(self) -> None: - pass + self.amount.set("") if __name__ == '__main__': window = Window()