diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..da7c527
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+pencil.png
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 26d3352..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
diff --git a/.idea/autoDrawGUI.iml b/.idea/autoDrawGUI.iml
deleted file mode 100644
index b6731d8..0000000
--- a/.idea/autoDrawGUI.iml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index b95d966..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 105ce2d..0000000
--- a/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 30ce026..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 5c36635..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..a1af42c
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,11 @@
+{
+ "python.analysis.autoImportCompletions": false,
+ "python.analysis.typeCheckingMode": "standard",
+ "github.copilot.enable": {
+ "*": false,
+ "plaintext": false,
+ "markdown": false,
+ "scminput": false,
+ "python": true
+ }
+}
\ No newline at end of file
diff --git a/geo/__pycache__/basic.cpython-313.pyc b/geo/__pycache__/basic.cpython-313.pyc
new file mode 100644
index 0000000..de7cdc0
Binary files /dev/null and b/geo/__pycache__/basic.cpython-313.pyc differ
diff --git a/geo/__pycache__/triangles.cpython-313.pyc b/geo/__pycache__/triangles.cpython-313.pyc
new file mode 100644
index 0000000..c596362
Binary files /dev/null and b/geo/__pycache__/triangles.cpython-313.pyc differ
diff --git a/geo/basic.py b/geo/basic.py
index 1ad00b6..60314d8 100644
--- a/geo/basic.py
+++ b/geo/basic.py
@@ -2,57 +2,46 @@
blk = (0,0,0)
-def rect(height, length, fill, source):
- t = turtle.Turtle()
+def rect(height: int, length: int, fill: bool, source):
+ rt = turtle.Turtle()
+ rt.hideturtle()
+ rt.penup()
+ rt.goto(0, 0)
+ rt.setheading(0)
+ rt.pendown()
+ rt.speed(0)
+ if fill and source:
+ rt.color(source)
+ rt.begin_fill()
+ else:
+ rt.color(source if source else blk)
+ for _ in range(2):
+ rt.forward(length)
+ rt.left(90)
+ rt.forward(height)
+ rt.left(90)
+ if fill and source:
+ rt.end_fill()
+
+
+
+def carr(cote : int, fill, source):
+ ct = turtle.Turtle()
+ ct.speed(0)
if source == None:
- t.color(blk)
+ ct.color(blk)
elif fill == True and bool(source) == True:
fcolor = source
- t.color(fcolor)
- t.begin_fill()
-
- t.forward(length)
- t.left(90)
- t.forward(height)
- t.left(90)
- t.forward(length)
- t.left(90)
- t.forward(height)
- if fill:
- t.end_fill()
-
-
-def carr(cote, fill, source):
- t = turtle.Turtle()
- if source == None:
- t.color(blk)
- elif fill == True and bool(source) == True:
- fcolor = source
- t.color(fcolor)
- t.begin_fill()
+ ct.color(fcolor)
+ ct.begin_fill()
for x in range(0, 5):
- t.forward(cote)
- t.left(90)
+ ct.forward(cote)
+ ct.left(90)
if fill == True:
- t.end_fill()
+ ct.end_fill()
-def triang(cote, fill, source):
- t = turtle.Turtle()
- if source == None:
- t.color(blk)
- elif fill == True and bool(source) == True:
- fcolor = source
- t.color(fcolor)
- t.begin_fill()
-
- for x in range(1, 4):
- t.forward(cote)
- t.left(360 / 3)
- if fill == True:
- t.end_fill()
-
def circle(rad, fill, source):
t = turtle.Turtle()
diff --git a/geo/triangles.py b/geo/triangles.py
index fe1bd2d..8055d92 100644
--- a/geo/triangles.py
+++ b/geo/triangles.py
@@ -4,19 +4,21 @@
blk = (0,0,0)
def tri_equi(cote, fill, source):
- t = turtle.Turtle()
+ trit = turtle.Turtle()
+ trit.speed(0)
+ trit.hideturtle()
if source == None:
- t.color(blk)
+ trit.color(blk)
elif fill == True and bool(source) == True:
fcolor = source
- t.color(fcolor)
- t.begin_fill()
+ trit.color(fcolor)
+ trit.begin_fill()
for x in range(1, 4):
- t.forward(cote)
- t.left(360 / 3)
+ trit.forward(cote)
+ trit.left(360 / 3)
if fill == True:
- t.end_fill()
+ trit.end_fill()
def tri_iso(side, base, fill, source):
t = turtle.Turtle()
diff --git a/gui.py b/gui.py
deleted file mode 100644
index 2e20a73..0000000
--- a/gui.py
+++ /dev/null
@@ -1,117 +0,0 @@
-from tkinter import *
-from tkinter import ttk
-from geo import *
-
-root = Tk()
-root.title("autoDraw")
-root.geometry("300x265")
-icon = PhotoImage(file="pencil.png")
-root.iconphoto(True, icon)
-root.resizable(0, 0)
-root.wm_attributes("-topmost", 1)
-
-fr = ttk.Frame(root, padding=10)
-fr.pack(fill="both", expand=True)
-
-############### Variable Definitions ###################
-en2var = StringVar()
-en3var = StringVar()
-chkvar1 = IntVar(value=0)
-chkvar3 = IntVar(value=0)
-comVar = StringVar()
-lbl2Text = StringVar()
-lbl3Text = StringVar()
-
-################ Functions ################
-def updateLabel(*args):
- shape = comVar.get()
- if shape == "Rectangle":
- en3.config(state="normal")
- lbl2Text.set("Length:")
- lbl3Text.set("Height:")
- elif shape == "Square":
- lbl2Text.set("Side:")
- lbl3Text.set("-")
- en3.config(state="disabled")
- elif shape == "Triangle":
- lbl2Text.set("Side:")
- lbl3Text.set("-")
- en3.config(state="disabled")
- else:
- lbl2Text.set("")
- lbl3Text.set("")
-
-def updateCheck(*args):
- if chkvar3.get() == 1:
- scl.config(state="normal", troughcolor="lightgray", fg="black")
- obtn.config(state="normal")
- else:
- scl.config(state="disabled", troughcolor="gray", fg="gray")
- obtn.config(state="disabled")
- if chkvar1.get() == 1:
- cbtn.config(state="normal")
- elif chkvar1.get() == 0:
- cbtn.config(state="disabled")
-
-################ Widget Creation ################
-# Dropdown
-lbl = ttk.Label(fr, text="Shape:")
-com = ttk.Combobox(fr, textvariable=comVar, values=["Rectangle", "Square", "Triangle"])
-com.current(0)
-com.config(state="readonly")
-
-# Entry labels and boxes
-lbl2 = ttk.Label(fr, textvariable=lbl2Text)
-en2 = ttk.Entry(fr, textvariable=en2var)
-
-lbl3 = ttk.Label(fr, textvariable=lbl3Text)
-en3 = ttk.Entry(fr, textvariable=en3var)
-
-# Outline size
-lbl4 = ttk.Label(fr, text="Outline Size:")
-scl = Scale(fr, from_=0, to=20, orient="horizontal", showvalue=True, state="disabled")
-
-# Checkbox frame
-check_frame = ttk.Frame(fr)
-chk1 = ttk.Checkbutton(check_frame, text="Fill", variable=chkvar1)
-chk3 = ttk.Checkbutton(check_frame, text="Outline", variable=chkvar3)
-
-# Buttons
-cbtn = ttk.Button(fr, text="🎨 Fill Color", state="disabled")
-obtn = ttk.Button(fr, text="🖊 Outline Color", state="disabled")
-dbtn = ttk.Button(fr, text="🖌 Draw !")
-########################Traces#########################
-comVar.trace_add("write", updateLabel)
-chkvar3.trace_add("write", updateCheck)
-chkvar1.trace_add("write", updateCheck)
-################ Layout ################
-lbl.grid(row=0, column=0, sticky="w", padx=5, pady=5)
-com.grid(row=0, column=1, columnspan=2, sticky="ew", pady=5)
-
-lbl2.grid(row=1, column=0, sticky="w", padx=5)
-en2.grid(row=1, column=1, columnspan=2, sticky="ew", pady=3)
-
-lbl3.grid(row=2, column=0, sticky="w", padx=5)
-en3.grid(row=2, column=1, columnspan=2, sticky="ew", pady=3)
-
-lbl4.grid(row=3, column=0, sticky="w", padx=5)
-scl.grid(row=3, column=1, columnspan=2, sticky="ew", pady=3)
-
-check_frame.grid(row=4, column=0, columnspan=3, pady=5)
-chk1.grid(row=0, column=0, padx=10)
-chk3.grid(row=0, column=1, padx=10)
-
-cbtn.grid(row=5, column=0, columnspan=2, sticky="ew", padx=5, pady=5)
-obtn.grid(row=5, column=2, sticky="ew", padx=5, pady=5)
-dbtn.grid(row=6, column=0, columnspan=3, sticky="ew", pady=5)
-# Make entries and combo expand
-fr.columnconfigure(1, weight=1)
-fr.columnconfigure(2, weight=1)
-
-# Initialize labels and states
-updateLabel()
-updateCheck()
-
-root.mainloop()
-
-#Icon made by Freepik from www.flaticon.com
\ No newline at end of file
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..6723fcb
--- /dev/null
+++ b/main.py
@@ -0,0 +1,253 @@
+import turtle
+from tkinter import * # type: ignore
+from tkinter import ttk
+from tkinter import colorchooser
+from geo.basic import *
+from geo.triangles import *
+from tkinter import messagebox as msg
+
+#Setup
+blk = (0, 0, 0)
+root = Tk()
+try:
+ icon = PhotoImage(file="pencil.png")
+ root.iconphoto(False, icon)
+ root.title("autoDraw")
+ root.geometry("300x265")
+ root.resizable(0, 0) # type: ignore
+ root.wm_attributes("-topmost", 1)
+ screen = turtle.Screen()
+ window = screen.getcanvas().winfo_toplevel()
+ window.protocol("WM_DELETE_WINDOW", window.withdraw) #type: ignore
+ screen.setup(500, 500)
+ screen.title("autoDraw")
+ window.withdraw() #type: ignore
+ turtle.hideturtle()
+ fr = ttk.Frame(root, padding=10)
+ fr.pack(fill="both", expand=True)
+ ############### Variable Definitions ###################
+ en2var = IntVar(value=None)
+ en3var = IntVar(value=None)
+ chkvar1 = IntVar()
+ chkvar3 = IntVar()
+ comVar = StringVar()
+ lbl2Text = StringVar()
+ lbl3Text = StringVar()
+ sclVar = IntVar(value=0)
+
+ ################ Functions ################
+ def updateLabel(*args):
+ shape = comVar.get()
+ if shape == "Rectangle":
+ en3.config(state="normal")
+ lbl2Text.set("Length:")
+ lbl3Text.set("Height:")
+ elif shape == "Square":
+ lbl2Text.set("Side:")
+ lbl3Text.set("-")
+ en3.config(state="disabled")
+ elif shape == "Triangle":
+ lbl2Text.set("Side:")
+ lbl3Text.set("-")
+ en3.config(state="disabled")
+ else:
+ lbl2Text.set("")
+ lbl3Text.set("")
+
+ def updateCheck(*args):
+ if chkvar3.get() == 1:
+ scl.config(state="normal", troughcolor="lightgray", fg="black")
+ obtn.config(state="normal")
+ else:
+ scl.config(state="disabled", troughcolor="gray", fg="gray")
+ obtn.config(state="disabled")
+ if chkvar1.get() == 1:
+ cbtn.config(state="normal")
+ elif chkvar1.get() == 0:
+ cbtn.config(state="disabled")
+ class Logic:
+ def __init__(self) -> None:
+ self.rect = rect
+ self.carr = carr
+ self.tri_equi = tri_equi
+ self.outColored = None
+ self.outliner = turtle.Turtle()
+ def cChooser(self, outline, fillcolor):
+ gui_chooser = colorchooser.askcolor()
+ if gui_chooser[1] is not None:
+ if outline:
+ self.outColor = gui_chooser[1]
+ self.outColored
+ elif outline == False:
+ self.chosen_c = gui_chooser[1]
+ elif gui_chooser[1] is None:
+ no_color = msg.showwarning("Error", "No color selected, please select a color")
+ if no_color == "ok":
+ pass
+ def logicGetter(self):
+ self.shape = comVar.get()
+ self.outline = chkvar3.get()
+ self.filled = chkvar1.get()
+ self.m1 = int(en2var.get())
+ self.m2 = int(en3var.get())
+ self.outSize = float(sclVar.get())
+ while True:
+ if self.shape == "Square" and self.m1 <= 0:
+ msg.showerror("Error", "Please enter a valid size")
+ break
+ elif self.shape == "Rectangle" and (self.m1 <= 0 or self.m2 <= 0):
+ msg.showerror("Error", "Please enter a valid size")
+ break
+ elif self.shape == "Triangle" and self.m1 <= 0:
+ msg.showerror("Error", "Please enter a valid size")
+ break
+ else:
+ self.logicCaller()
+ def logicCaller(self):
+ if self.outline and self.filled:
+ self.logic(True, True)
+ elif self.outline and not self.filled:
+ self.logic(False, True)
+ elif not self.outline and self.filled:
+ self.logic(True, False)
+ elif not self.outline and not self.filled:
+ self.logic(False, False)
+ def logic(self, filling, outlined):
+ match self.shape:
+ case "Square":
+ window.deiconify() #type: ignore
+ if filling:
+ self.carr(self.m1, True, self.chosen_c)
+ if outlined and self.outColored:
+ self.outDraw(self.carr, self.outSize, self.chosen_c)
+ elif outlined and not self.outColored:
+ self.outDraw(self.carr, self.outSize, None)
+ elif not outlined and not filling and not self.outColored:
+ self.carr(self.m1, False, None)
+ turtle.done()
+ case "Rectangle":
+ window.deiconify() #type: ignore
+ if filling:
+ self.rect(self.m1, self.m2, True, self.chosen_c)
+ elif not filling:
+ self.rect(self.m1, self.m2, False, None)
+ if outlined and self.outColored:
+ self.outDraw(self.rect, self.outSize, self.outColor)
+ elif outlined and not self.outColored:
+ self.outDraw(self.rect, self.outSize, None)
+ elif not outlined and not filling and not self.outColored:
+ self.rect(self.m1, self.m2, False, None)
+ turtle.done()
+ case "Triangle":
+ window.deiconify() #type: ignore
+ if filling:
+ self.tri_equi(self.m1, True, self.chosen_c)
+ elif not filling and not outlined:
+ self.tri_equi(self.m1, False, None)
+ if outlined and self.outColored:
+ self.outDraw(self.tri_equi, self.outSize, self.outColor)
+ elif outlined and not self.outColored:
+ self.outDraw(self.tri_equi, self.outSize, None)
+ turtle.done()
+ def outDraw(self, shape, size, src):
+ self.outliner.pensize(size)
+ self.outliner.penup()
+ self.outliner.setheading(0)
+ self.outliner.pendown()
+ self.outliner.speed(0)
+ self.outliner.hideturtle()
+ if bool(src) == True:
+ self.outliner.color(src)
+ elif bool(src) == False:
+ self.outliner.color(self.outColor)
+ if shape == self.tri_equi:
+ self.outTriEqui(self.m1)
+ elif shape == self.rect:
+ self.outRect(self.m1, self.m2)
+ elif shape == self.carr:
+ self.outSq(self.m1)
+ def outSq(self, size):
+ for x in range(4):
+ self.outliner.forward(size)
+ self.outliner.left(90)
+ def outRect(self, height, width):
+ for _ in range(2):
+ self.outliner.forward(width)
+ self.outliner.left(90)
+ self.outliner.forward(height)
+ self.outliner.left(90)
+ def outTriEqui(self, side):
+ for _ in range(3):
+ self.outliner.forward(side)
+ self.outliner.left(120)
+
+ logic = Logic()
+ def cAsk(src: str):
+ if src == "outline":
+ logic.cChooser(True, False)
+ elif src == "fill":
+ logic.cChooser(False, True)
+ ################ Widget Creation ################
+ # Dropdown
+ lbl = ttk.Label(fr, text="Shape:")
+ com = ttk.Combobox(fr, textvariable=comVar, values=["Rectangle", "Square", "Triangle"])
+ com.current(0)
+ com.config(state="readonly")
+
+ # Entry labels and boxes
+ lbl2 = ttk.Label(fr, textvariable=lbl2Text)
+ en2 = ttk.Entry(fr, textvariable=en2var)
+
+ lbl3 = ttk.Label(fr, textvariable=lbl3Text)
+ en3 = ttk.Entry(fr, textvariable=en3var)
+
+ # Outline size
+ lbl4 = ttk.Label(fr, text="Outline Size:")
+ scl = Scale(fr, from_=0, to=20, orient="horizontal", showvalue=True, state="disabled", variable=sclVar)
+
+ # Checkbox frame
+ check_frame = ttk.Frame(fr)
+ chk1 = ttk.Checkbutton(check_frame, text="Fill", variable=chkvar1, onvalue=True, offvalue=False)
+ chk3 = ttk.Checkbutton(check_frame, text="Outline", variable=chkvar3, onvalue=True, offvalue=False)
+ # Buttons
+ cbtn = ttk.Button(fr, text="🎨 Fill Color", state="disabled", command= lambda: cAsk("fill"))
+ obtn = ttk.Button(fr, text="🖊 Outline Color", state="disabled", command= lambda: cAsk("outline"))
+ dbtn = ttk.Button(fr, text="🖌 Draw !", command=logic.logicGetter)
+ ########################Traces#########################
+ comVar.trace_add("write", updateLabel)
+ chkvar3.trace_add("write", updateCheck)
+ chkvar1.trace_add("write", updateCheck)
+ ################ Layout ################
+ lbl.grid(row=0, column=0, sticky="w", padx=5, pady=5)
+ com.grid(row=0, column=1, columnspan=2, sticky="ew", pady=5)
+
+ lbl2.grid(row=1, column=0, sticky="w", padx=5)
+ en2.grid(row=1, column=1, columnspan=2, sticky="ew", pady=3)
+
+ lbl3.grid(row=2, column=0, sticky="w", padx=5)
+ en3.grid(row=2, column=1, columnspan=2, sticky="ew", pady=3)
+
+ lbl4.grid(row=3, column=0, sticky="w", padx=5)
+ scl.grid(row=3, column=1, columnspan=2, sticky="ew", pady=3)
+
+ check_frame.grid(row=4, column=0, columnspan=3, pady=5)
+ chk1.grid(row=0, column=0, padx=10)
+ chk3.grid(row=0, column=1, padx=10)
+
+ cbtn.grid(row=5, column=0, columnspan=2, sticky="ew", padx=5, pady=5)
+ obtn.grid(row=5, column=2, sticky="ew", padx=5, pady=5)
+ dbtn.grid(row=6, column=0, columnspan=3, sticky="ew", pady=5)
+ # Make entries and combo expand
+ fr.columnconfigure(1, weight=1)
+ fr.columnconfigure(2, weight=1)
+
+ # Initialize labels and states
+ updateLabel()
+ updateCheck()
+
+ root.mainloop()
+except Exception as e:
+ err = msg.showerror("Error", f"An error occurred: {e}")
+ if err == "ok":
+ root.quit()
+#Window Icon made by Freepik from www.flaticon.com
\ No newline at end of file
diff --git a/pencil.png b/pencil.png
deleted file mode 100644
index 403b2e1..0000000
Binary files a/pencil.png and /dev/null differ
diff --git a/tests.md b/tests.md
new file mode 100644
index 0000000..78a7767
--- /dev/null
+++ b/tests.md
@@ -0,0 +1,29 @@
+autoDrawGUI tests:
+ 1.UI/ UX: yes
+ icons : yes
+ buttons: yes
+ sliders: yes
+ graying outs: yes
+ 2.Shapes:
+ Rectangle: yes
+ outline:
+ color:yes
+ size: yes
+ fill: yes
+ measurements: yes
+ Square:
+ outline:yes
+ color:yes
+ size:yes
+ fill:yes
+ measurments:yes
+ triangle: (equilateral ONLY): yes
+ outline:yes
+ color:yes
+ size:yes
+ fill:yes
+ measurments:yes
+ 3.Error Handling: yes
+ try/except: yes
+ msgboxes: yes
+ ZeroDivisionError: yes