Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
47ca224e2a | |||
7dd4af8db2 | |||
|
def7acc30c | ||
6872124632 | |||
|
02c34ca299 | ||
|
d4de4a8699 | ||
|
11a43331ad | ||
ed00996424 | |||
8521680069 | |||
bdf51e9f16 | |||
1fc537a36c | |||
1116f84ca0 | |||
550c8f4458 | |||
5d33d9606f | |||
040b260a88 | |||
|
6aa3dc2cb4 | ||
|
8aec2319d1 | ||
|
1bbade4884 | ||
|
e05e288875 | ||
6ff054c84b | |||
86afc9b2f8 | |||
8db34d386c | |||
0aad49aaec | |||
ad6a8a4e3c |
@ -23,3 +23,12 @@ To run tests:
|
||||
`pip3 install -r requirements.txt`
|
||||
|
||||
`python3 app.py`
|
||||
|
||||
|
||||
### Gestures module
|
||||
`cd gestures`
|
||||
|
||||
`pip install -r requirements.txt`
|
||||
|
||||
`python gesture_recognition.py `
|
||||
|
||||
|
200
client/app.py
200
client/app.py
@ -1,13 +1,9 @@
|
||||
import tkinter as tk
|
||||
|
||||
import requests
|
||||
|
||||
FONT = ("Verdana", 12)
|
||||
FONT_B = ("Verdana", 12, 'bold')
|
||||
FONT_LARGE = ("Verdana", 20)
|
||||
URL = "http://localhost:8000/api/authenticate"
|
||||
URL_REGISTER = "http://localhost:8000/api/register"
|
||||
URL_PROFILE = "http://localhost:8000/api/profile"
|
||||
from constants import LOGIN_VIEW_NAME
|
||||
from views.login_view import LoginView
|
||||
from views.main_view import MainView
|
||||
from views.register_view import RegisterView
|
||||
|
||||
|
||||
class SmartPicasso(tk.Tk):
|
||||
@ -16,7 +12,7 @@ class SmartPicasso(tk.Tk):
|
||||
tk.Tk.__init__(self, *args, **kwargs)
|
||||
container = tk.Frame(self)
|
||||
self.title('SmartPicasso')
|
||||
self.geometry('610x460')
|
||||
self.geometry('800x600')
|
||||
|
||||
container.pack(side="top", fill="both", expand=True)
|
||||
|
||||
@ -28,11 +24,11 @@ class SmartPicasso(tk.Tk):
|
||||
for F in (LoginView, MainView, RegisterView):
|
||||
frame = F(container, self)
|
||||
|
||||
self.frames[F] = frame
|
||||
self.frames[F.get_view_name()] = frame
|
||||
|
||||
frame.grid(row=0, column=0, sticky="nsew")
|
||||
|
||||
self.show_frame(LoginView)
|
||||
self.show_frame(LOGIN_VIEW_NAME)
|
||||
|
||||
def show_frame(self, view, token=None):
|
||||
frame = self.frames[view]
|
||||
@ -42,187 +38,5 @@ class SmartPicasso(tk.Tk):
|
||||
frame.token = token
|
||||
|
||||
|
||||
class LoginView(tk.Frame):
|
||||
|
||||
def __init__(self, parent, controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE)
|
||||
label.pack(pady=10, padx=10)
|
||||
|
||||
label1 = tk.Label(self, text='Login:', font=FONT)
|
||||
label1.pack()
|
||||
|
||||
input1 = tk.Entry(self)
|
||||
input1.pack()
|
||||
|
||||
label2 = tk.Label(self, text='Password:', font=FONT)
|
||||
label2.pack()
|
||||
|
||||
input2 = tk.Entry(self, show="*")
|
||||
input2.pack()
|
||||
|
||||
button = tk.Button(self, text="Login", font=FONT,
|
||||
command=lambda: self.login(controller, input1.get(), input2.get()))
|
||||
button.pack()
|
||||
|
||||
button2 = tk.Button(self, text="Register", font=FONT, command=lambda: controller.show_frame(RegisterView))
|
||||
button2.pack()
|
||||
|
||||
def login(self, controller, login, password):
|
||||
print(login)
|
||||
print(password)
|
||||
data = {
|
||||
"email": str(login),
|
||||
"password": str(password)
|
||||
}
|
||||
resp = requests.post(URL, json=data)
|
||||
print(resp)
|
||||
if resp.status_code == 200:
|
||||
response = resp.json()
|
||||
token = response['token']
|
||||
|
||||
controller.show_frame(MainView, token)
|
||||
else:
|
||||
print("bad pass")
|
||||
bad_pass_label = tk.Label(self, text='Wrong login/password!', font=FONT)
|
||||
bad_pass_label.pack()
|
||||
return ()
|
||||
|
||||
|
||||
class MainView(tk.Frame):
|
||||
|
||||
def __init__(self, parent, controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
self.frames = {}
|
||||
self.token = ''
|
||||
for F in (ProfileView,):
|
||||
frame = F(parent, controller)
|
||||
|
||||
self.frames[F] = frame
|
||||
|
||||
frame.grid(row=0, column=0, sticky="nsew")
|
||||
label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE)
|
||||
label.pack(pady=10, padx=10)
|
||||
label_u = tk.Label(self, text="Main menu", font=FONT)
|
||||
label_u.pack(pady=10, padx=10)
|
||||
|
||||
button_profile = tk.Button(self, text="My profile", font=FONT,
|
||||
command=lambda: self.show_frame(ProfileView))
|
||||
button_profile.pack()
|
||||
|
||||
def show_frame(self, view):
|
||||
frame = self.frames[view]
|
||||
frame.tkraise()
|
||||
|
||||
if self.token:
|
||||
print(self.token)
|
||||
frame.token = self.token
|
||||
frame.start()
|
||||
|
||||
|
||||
class RegisterView(tk.Frame):
|
||||
|
||||
def __init__(self, parent, controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE)
|
||||
label.pack(pady=10, padx=10)
|
||||
label_u = tk.Label(self, text="Register", font=FONT)
|
||||
label_u.pack(pady=10, padx=10)
|
||||
|
||||
label0 = tk.Label(self, text='Email:', font=FONT)
|
||||
label0.pack()
|
||||
|
||||
input0 = tk.Entry(self)
|
||||
input0.pack()
|
||||
|
||||
label1 = tk.Label(self, text='Login:', font=FONT)
|
||||
label1.pack()
|
||||
|
||||
input1 = tk.Entry(self)
|
||||
input1.pack()
|
||||
|
||||
label2 = tk.Label(self, text='Password:', font=FONT)
|
||||
label2.pack()
|
||||
|
||||
input2 = tk.Entry(self, show="*")
|
||||
input2.pack()
|
||||
|
||||
label3 = tk.Label(self, text='First name:', font=FONT)
|
||||
label3.pack()
|
||||
|
||||
input3 = tk.Entry(self)
|
||||
input3.pack()
|
||||
|
||||
label4 = tk.Label(self, text='Last name:', font=FONT)
|
||||
label4.pack()
|
||||
|
||||
input4 = tk.Entry(self)
|
||||
input4.pack()
|
||||
|
||||
button1 = tk.Button(self, text="Register", font=FONT,
|
||||
command=lambda: self.register(controller, input0.get(), input1.get(), input2.get(),
|
||||
input3.get(), input4.get()))
|
||||
button1.pack()
|
||||
|
||||
button2 = tk.Button(self, text="Cancel", font=FONT, command=lambda: controller.show_frame(LoginView))
|
||||
button2.pack()
|
||||
|
||||
def register(self, controller, email, login, passw, name, lastname):
|
||||
data = {
|
||||
"email": str(email),
|
||||
"password": str(passw),
|
||||
"profile": {
|
||||
"username": str(login),
|
||||
"first_name": str(name),
|
||||
"last_name": str(lastname)
|
||||
}
|
||||
}
|
||||
print(data)
|
||||
response = requests.post(URL_REGISTER, json=data)
|
||||
print(response)
|
||||
if response.status_code == 201:
|
||||
response = response.json()
|
||||
controller.show_frame(LoginView)
|
||||
else:
|
||||
print("sth wrong")
|
||||
bad_pass_label = tk.Label(self, text='Something went wrong!', font=FONT)
|
||||
bad_pass_label.pack()
|
||||
return ()
|
||||
|
||||
|
||||
class ProfileView(tk.Frame):
|
||||
|
||||
def __init__(self, parent, controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
self.token = ''
|
||||
label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE)
|
||||
label.pack(pady=10, padx=10)
|
||||
label_l1 = tk.Label(self, text="Login:", font=FONT_B)
|
||||
label_l1.pack(pady=10, padx=10)
|
||||
self.label_username = tk.Label(self, text='', font=FONT)
|
||||
self.label_username.pack(pady=10, padx=10)
|
||||
label_n1 = tk.Label(self, text="Name:", font=FONT_B)
|
||||
label_n1.pack(pady=10, padx=10)
|
||||
self.label_first_name = tk.Label(self, text='', font=FONT)
|
||||
self.label_first_name.pack(pady=10, padx=10)
|
||||
label_ln1 = tk.Label(self, text="Last name", font=FONT_B)
|
||||
label_ln1.pack(pady=10, padx=10)
|
||||
self.label_last_name = tk.Label(self, text='', font=FONT)
|
||||
self.label_last_name.pack(pady=10, padx=10)
|
||||
|
||||
button_profile = tk.Button(self, text="Back", font=FONT,
|
||||
command=lambda: controller.show_frame(MainView, self.token))
|
||||
button_profile.pack()
|
||||
|
||||
def start(self):
|
||||
headers = {'Authorization': 'Bearer ' + self.token}
|
||||
resp = requests.get(URL_PROFILE, headers=headers)
|
||||
response = resp.json()
|
||||
print(response)
|
||||
self.label_username['text'] = response['profile']['username']
|
||||
self.label_first_name['text'] = response['profile']['first_name']
|
||||
self.label_last_name['text'] = response['profile']['last_name']
|
||||
|
||||
|
||||
app = SmartPicasso()
|
||||
app.mainloop()
|
||||
|
17
client/constants.py
Normal file
17
client/constants.py
Normal file
@ -0,0 +1,17 @@
|
||||
FONT = ("Verdana", 12)
|
||||
FONT_SM = ("Verdana", 10)
|
||||
FONT_B = ("Verdana", 12, 'bold')
|
||||
FONT_LARGE = ("Verdana", 20)
|
||||
|
||||
URL_LOGIN = "http://localhost:8000/api/authenticate"
|
||||
URL_REGISTER = "http://localhost:8000/api/register"
|
||||
URL_PROFILE = "http://localhost:8000/api/profile"
|
||||
URL_PROJECTS = "http://localhost:8000/api/projects"
|
||||
|
||||
LOGIN_VIEW_NAME = 'login_view'
|
||||
MAIN_VIEW_NAME = 'main_view'
|
||||
REGISTER_VIEW_NAME = 'register_view'
|
||||
PROFILE_VIEW_NAME = 'profile_view'
|
||||
PROJECT_VIEW_NAME = 'project_view'
|
||||
PROJECTS_ADD_VIEW_NAME = 'projects_add_view'
|
||||
PROJECTS_VIEW_NAME = 'projects_view'
|
57
client/gestures/gesture_recognition.py
Normal file
57
client/gestures/gesture_recognition.py
Normal file
@ -0,0 +1,57 @@
|
||||
import cv2
|
||||
import mediapipe as mp
|
||||
|
||||
import gestures.simple_gestures_lib as sgest
|
||||
|
||||
|
||||
class MyVideoCapture:
|
||||
|
||||
def __init__(self):
|
||||
# Open the video source
|
||||
self.vid = cv2.VideoCapture(0)
|
||||
self.vid.set(3, 300)
|
||||
self.vid.set(4, 150)
|
||||
self.mp_drawing = mp.solutions.drawing_utils
|
||||
self.mp_hands = mp.solutions.hands
|
||||
self.hands = self.mp_hands.Hands(
|
||||
min_detection_confidence=0.7, min_tracking_confidence=0.7)
|
||||
if not self.vid.isOpened():
|
||||
raise ValueError("Unable to open video source", 0)
|
||||
# Get video source width and height
|
||||
self.width = self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)
|
||||
self.height = self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
|
||||
|
||||
def get_frame(self):
|
||||
if self.vid.isOpened():
|
||||
success, image = self.vid.read()
|
||||
image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
|
||||
image.flags.writeable = False
|
||||
results = self.hands.process(image)
|
||||
|
||||
image.flags.writeable = True
|
||||
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
|
||||
if results.multi_hand_landmarks:
|
||||
for hand_landmarks in results.multi_hand_landmarks:
|
||||
self.mp_drawing.draw_landmarks(
|
||||
image, hand_landmarks, self.mp_hands.HAND_CONNECTIONS)
|
||||
# if cv2.waitKey(33) == ord('s'):
|
||||
# fingers = {'index': (), 'middle': (), 'ring': (), 'pinky': ()}
|
||||
fingers = {}
|
||||
if results.multi_hand_landmarks:
|
||||
for hand_landmarks in results.multi_hand_landmarks:
|
||||
fingers['index'] = sgest.check_index_finger(hand_landmarks)
|
||||
fingers['start_stop'] = sgest.get_start_stop(hand_landmarks)
|
||||
fingers['ninja'] = sgest.search_for_ninja_turtle(hand_landmarks)
|
||||
fingers['middle'] = sgest.check_middle_finger(hand_landmarks)
|
||||
# fingers['ring'] = sgest.check_ring_finger(hand_landmarks)
|
||||
# fingers['pinky'] = sgest.check_pinky_finger(hand_landmarks)
|
||||
else:
|
||||
fingers = None
|
||||
return fingers, image, success
|
||||
|
||||
# Release the video source when the object is destroyed
|
||||
def release(self):
|
||||
print('My video capture delete')
|
||||
if self.vid.isOpened():
|
||||
self.vid.release()
|
||||
self.hands.close()
|
92
client/gestures/simple_gestures_lib.py
Normal file
92
client/gestures/simple_gestures_lib.py
Normal file
@ -0,0 +1,92 @@
|
||||
from math import sqrt
|
||||
|
||||
INDEX_FINGER_TOP = 8
|
||||
INDEX_FINGER_BOTTOM = 5
|
||||
MIDDLE_FINGER_TOP = 12
|
||||
MIDDLE_FINGER_BOTTOM = 9
|
||||
RING_FINGER_TOP = 16
|
||||
RING_FINGER_BOTTOM = 13
|
||||
PINKY_FINGER_TOP = 20
|
||||
PINKY_FINGER_BOTTOM = 17
|
||||
THUMB_TOP = 4
|
||||
THUMB_CENTER = 3
|
||||
THUMB_BOTTOM = 2
|
||||
|
||||
|
||||
def calculate_distance(ax, ay, bx, by):
|
||||
distance = sqrt(((bx - ax) ** 2 + (by - ay) ** 2))
|
||||
return distance
|
||||
|
||||
|
||||
def get_start_stop(hand_landmarks):
|
||||
index_finger = check_index_finger(hand_landmarks)
|
||||
middle_finger = check_middle_finger(hand_landmarks)
|
||||
ring_finger = check_ring_finger(hand_landmarks)
|
||||
pinky_finger = check_pinky_finger(hand_landmarks)
|
||||
is_thumb_near_index = is_thumb_near_index_finger(hand_landmarks)
|
||||
|
||||
if not index_finger['straight'] and middle_finger['straight'] and ring_finger['straight'] and pinky_finger['straight'] and is_thumb_near_index:
|
||||
return 'start'
|
||||
else:
|
||||
thumb_top_y = hand_landmarks.landmark[THUMB_TOP].y
|
||||
thumb_bottom_y = hand_landmarks.landmark[THUMB_BOTTOM].y
|
||||
is_thumb_straight = check_finger(hand_landmarks, THUMB_TOP, THUMB_BOTTOM)['straight']
|
||||
if is_thumb_straight:
|
||||
if thumb_bottom_y + 0.1 < thumb_top_y:
|
||||
return 'stop'
|
||||
else:
|
||||
return 'nothing'
|
||||
else:
|
||||
return 'nothing'
|
||||
|
||||
def search_for_ninja_turtle(hand_landmarks):
|
||||
index_finger = check_index_finger(hand_landmarks)
|
||||
pinky_finger = check_pinky_finger(hand_landmarks)
|
||||
middle_finger = check_middle_finger(hand_landmarks)
|
||||
ring_finger = check_ring_finger(hand_landmarks)
|
||||
if index_finger['straight'] and pinky_finger['straight'] and not middle_finger['straight'] and not ring_finger['straight']:
|
||||
#return 'ninja'
|
||||
return {'ninja': 'ninja', 'x': index_finger['x'], 'y': index_finger['y']}
|
||||
else:
|
||||
return 'nothing'
|
||||
|
||||
def check_index_finger(hand_landmarks):
|
||||
return check_finger(hand_landmarks, INDEX_FINGER_TOP, INDEX_FINGER_BOTTOM)
|
||||
|
||||
|
||||
def check_middle_finger(hand_landmarks):
|
||||
return check_finger(hand_landmarks, MIDDLE_FINGER_TOP, MIDDLE_FINGER_BOTTOM)
|
||||
|
||||
|
||||
def check_ring_finger(hand_landmarks):
|
||||
return check_finger(hand_landmarks, RING_FINGER_TOP, RING_FINGER_BOTTOM)
|
||||
|
||||
|
||||
def check_pinky_finger(hand_landmarks):
|
||||
return check_finger(hand_landmarks, PINKY_FINGER_TOP, PINKY_FINGER_BOTTOM)
|
||||
|
||||
|
||||
def check_finger(hand_landmarks, top_idx, bottom_idx):
|
||||
ax = hand_landmarks.landmark[top_idx].x
|
||||
ay = hand_landmarks.landmark[top_idx].y
|
||||
bx = hand_landmarks.landmark[bottom_idx].x
|
||||
by = hand_landmarks.landmark[bottom_idx].y
|
||||
distance_top_bottom = calculate_distance(ax, ay, bx, by)
|
||||
ax = hand_landmarks.landmark[bottom_idx].x
|
||||
ay = hand_landmarks.landmark[bottom_idx].y
|
||||
bx = hand_landmarks.landmark[0].x
|
||||
by = hand_landmarks.landmark[0].y
|
||||
distance_bottom_start = calculate_distance(ax, ay, bx, by)
|
||||
|
||||
if distance_bottom_start < distance_top_bottom + 0.05:
|
||||
straight = True
|
||||
else:
|
||||
straight = False
|
||||
return {'straight': straight, 'x': hand_landmarks.landmark[top_idx].x, 'y': hand_landmarks.landmark[top_idx].y}
|
||||
|
||||
|
||||
def is_thumb_near_index_finger(hand_landmarks):
|
||||
thumb_top = hand_landmarks.landmark[THUMB_TOP]
|
||||
index_finger_top = hand_landmarks.landmark[INDEX_FINGER_TOP]
|
||||
distance = calculate_distance(thumb_top.x, thumb_top.y, index_finger_top.x, index_finger_top.y)
|
||||
return distance < 0.1
|
BIN
client/image.png
Normal file
BIN
client/image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@ -1,2 +1,5 @@
|
||||
tk
|
||||
requests
|
||||
cv
|
||||
mediapipe
|
||||
Pillow
|
4
client/views/abstract_view.py
Normal file
4
client/views/abstract_view.py
Normal file
@ -0,0 +1,4 @@
|
||||
class AbstractView:
|
||||
@staticmethod
|
||||
def get_view_name() -> str:
|
||||
pass
|
58
client/views/login_view.py
Normal file
58
client/views/login_view.py
Normal file
@ -0,0 +1,58 @@
|
||||
import requests
|
||||
import tkinter as tk
|
||||
|
||||
from constants import FONT, FONT_LARGE, URL_LOGIN, LOGIN_VIEW_NAME, REGISTER_VIEW_NAME, MAIN_VIEW_NAME
|
||||
from views.abstract_view import AbstractView
|
||||
|
||||
|
||||
class LoginView(tk.Frame, AbstractView):
|
||||
|
||||
def __init__(self, parent, controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE)
|
||||
label.pack(pady=10, padx=10)
|
||||
|
||||
label1 = tk.Label(self, text='Login:', font=FONT)
|
||||
label1.pack()
|
||||
|
||||
input1 = tk.Entry(self)
|
||||
input1.insert(0, 'test@test.pl')
|
||||
input1.pack()
|
||||
|
||||
label2 = tk.Label(self, text='Password:', font=FONT)
|
||||
label2.pack()
|
||||
|
||||
input2 = tk.Entry(self, show="*")
|
||||
input2.insert(0, 'test123')
|
||||
input2.pack()
|
||||
|
||||
button = tk.Button(self, text="Login", font=FONT,
|
||||
command=lambda: self.login(controller, input1.get(), input2.get()))
|
||||
button.pack()
|
||||
|
||||
button2 = tk.Button(self, text="Register", font=FONT, command=lambda: controller.show_frame(REGISTER_VIEW_NAME))
|
||||
button2.pack()
|
||||
|
||||
@staticmethod
|
||||
def get_view_name() -> str:
|
||||
return LOGIN_VIEW_NAME
|
||||
|
||||
def login(self, controller, login, password):
|
||||
print(login)
|
||||
print(password)
|
||||
data = {
|
||||
"email": str(login),
|
||||
"password": str(password)
|
||||
}
|
||||
resp = requests.post(URL_LOGIN, json=data)
|
||||
print(resp)
|
||||
if resp.status_code == 200:
|
||||
response = resp.json()
|
||||
token = response['token']
|
||||
|
||||
controller.show_frame(MAIN_VIEW_NAME, token)
|
||||
else:
|
||||
print("bad pass")
|
||||
bad_pass_label = tk.Label(self, text='Wrong login/password!', font=FONT)
|
||||
bad_pass_label.pack()
|
||||
return ()
|
47
client/views/main_view.py
Normal file
47
client/views/main_view.py
Normal file
@ -0,0 +1,47 @@
|
||||
import tkinter as tk
|
||||
|
||||
from constants import FONT, FONT_LARGE, MAIN_VIEW_NAME, PROJECTS_VIEW_NAME, PROFILE_VIEW_NAME
|
||||
from views.profile_view import ProfileView
|
||||
from views.project_view import ProjectView
|
||||
from views.projects_add_view import ProjectsAddView
|
||||
from views.projects_view import ProjectsView
|
||||
from views.abstract_view import AbstractView
|
||||
|
||||
|
||||
class MainView(tk.Frame, AbstractView):
|
||||
|
||||
def __init__(self, parent, controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
self.frames = {}
|
||||
self.token = ''
|
||||
for F in (ProfileView, ProjectsView, ProjectsAddView, ProjectView):
|
||||
frame = F(parent, controller, self)
|
||||
|
||||
self.frames[F.get_view_name()] = frame
|
||||
|
||||
frame.grid(row=0, column=0, sticky="nsew")
|
||||
label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE)
|
||||
label.pack(pady=10, padx=10)
|
||||
label_u = tk.Label(self, text="Main menu", font=FONT)
|
||||
label_u.pack(pady=10, padx=10)
|
||||
|
||||
button_projects = tk.Button(self, text="Projects", font=FONT,
|
||||
command=lambda: self.show_frame(PROJECTS_VIEW_NAME))
|
||||
button_projects.pack()
|
||||
|
||||
button_profile = tk.Button(self, text="My profile", font=FONT,
|
||||
command=lambda: self.show_frame(PROFILE_VIEW_NAME))
|
||||
button_profile.pack()
|
||||
|
||||
@staticmethod
|
||||
def get_view_name() -> str:
|
||||
return MAIN_VIEW_NAME
|
||||
|
||||
def show_frame(self, view):
|
||||
frame = self.frames[view]
|
||||
frame.tkraise()
|
||||
|
||||
if self.token:
|
||||
print(self.token)
|
||||
frame.token = self.token
|
||||
frame.start()
|
43
client/views/profile_view.py
Normal file
43
client/views/profile_view.py
Normal file
@ -0,0 +1,43 @@
|
||||
import requests
|
||||
import tkinter as tk
|
||||
|
||||
from constants import FONT, FONT_B, FONT_LARGE, URL_PROFILE, PROFILE_VIEW_NAME, MAIN_VIEW_NAME
|
||||
from views.abstract_view import AbstractView
|
||||
|
||||
|
||||
class ProfileView(tk.Frame, AbstractView):
|
||||
|
||||
def __init__(self, parent, controller, main_view_controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
self.token = ''
|
||||
label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE)
|
||||
label.pack(pady=10, padx=10)
|
||||
label_l1 = tk.Label(self, text="Login:", font=FONT_B)
|
||||
label_l1.pack(pady=10, padx=10)
|
||||
self.label_username = tk.Label(self, text='', font=FONT)
|
||||
self.label_username.pack(pady=10, padx=10)
|
||||
label_n1 = tk.Label(self, text="Name:", font=FONT_B)
|
||||
label_n1.pack(pady=10, padx=10)
|
||||
self.label_first_name = tk.Label(self, text='', font=FONT)
|
||||
self.label_first_name.pack(pady=10, padx=10)
|
||||
label_ln1 = tk.Label(self, text="Last name", font=FONT_B)
|
||||
label_ln1.pack(pady=10, padx=10)
|
||||
self.label_last_name = tk.Label(self, text='', font=FONT)
|
||||
self.label_last_name.pack(pady=10, padx=10)
|
||||
|
||||
button_profile = tk.Button(self, text="Back", font=FONT,
|
||||
command=lambda: controller.show_frame(MAIN_VIEW_NAME, self.token))
|
||||
button_profile.pack()
|
||||
|
||||
@staticmethod
|
||||
def get_view_name() -> str:
|
||||
return PROFILE_VIEW_NAME
|
||||
|
||||
def start(self):
|
||||
headers = {'Authorization': 'Bearer ' + self.token}
|
||||
resp = requests.get(URL_PROFILE, headers=headers)
|
||||
response = resp.json()
|
||||
print(response)
|
||||
self.label_username['text'] = response['profile']['username']
|
||||
self.label_first_name['text'] = response['profile']['first_name']
|
||||
self.label_last_name['text'] = response['profile']['last_name']
|
172
client/views/project_view.py
Normal file
172
client/views/project_view.py
Normal file
@ -0,0 +1,172 @@
|
||||
import PIL.Image
|
||||
import PIL.ImageTk
|
||||
import tkinter as tk
|
||||
import os
|
||||
import cv2
|
||||
|
||||
from constants import PROJECT_VIEW_NAME, FONT, PROJECTS_VIEW_NAME
|
||||
from gestures.gesture_recognition import MyVideoCapture
|
||||
from views.abstract_view import AbstractView
|
||||
|
||||
|
||||
class ProjectView(tk.Frame, AbstractView):
|
||||
|
||||
def __init__(self, parent, controller, main_view_controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
self.token = ''
|
||||
self.window = controller
|
||||
self.main_view_controller = main_view_controller
|
||||
self.delay = 20
|
||||
self.canvas_width = 800
|
||||
self.canvas_height = 415
|
||||
self.start_draw = False
|
||||
self.vid = None
|
||||
self.vid_canvas = None
|
||||
self.canvas = None
|
||||
self.back_button = None
|
||||
self.clear_button = None
|
||||
self.save_button = None
|
||||
self.bottom_frame = None
|
||||
self.top_frame = None
|
||||
self.first_time = True
|
||||
self.other_gestures_flag_possible = False
|
||||
@staticmethod
|
||||
def get_view_name() -> str:
|
||||
return PROJECT_VIEW_NAME
|
||||
|
||||
def start(self):
|
||||
self.vid = MyVideoCapture()
|
||||
self.canvas_width = self.window.winfo_width()
|
||||
self.canvas_height = self.window.winfo_height() - 185
|
||||
self.top_frame = tk.Frame(self, relief=tk.RAISED, borderwidth=0)
|
||||
self.top_frame.pack(fill=tk.BOTH, side=tk.TOP)
|
||||
self.canvas = tk.Canvas(self.top_frame, width=self.canvas_width, height=self.canvas_height, bg="white")
|
||||
self.canvas.grid(row=0, column=0)
|
||||
|
||||
self.bottom_frame = tk.Frame(self, relief=tk.RAISED, borderwidth=1)
|
||||
self.bottom_frame.pack(fill=tk.BOTH, side=tk.BOTTOM)
|
||||
self.bottom_frame.columnconfigure(0, weight=1)
|
||||
self.bottom_frame.columnconfigure(1, weight=1)
|
||||
self.bottom_frame.columnconfigure(2, weight=15)
|
||||
self.back_button = tk.Button(self.bottom_frame, text="Back", font=FONT,
|
||||
command=lambda: self.back_to_projects_view())
|
||||
self.back_button.grid(row=0, column=0, sticky=tk.SW, pady=10, padx=5)
|
||||
self.clear_button = tk.Button(self.bottom_frame, text="Clear", font=FONT,
|
||||
command=lambda: self.clear_canvas())
|
||||
self.clear_button.grid(row=0, column=1, sticky=tk.SW, pady=10, padx=5)
|
||||
self.save_button = tk.Button(self.bottom_frame, text="Save", font=FONT,
|
||||
command=lambda: self.save())
|
||||
self.save_button.grid(row=0, column=2, sticky=tk.SW, pady=10, padx=5)
|
||||
self.vid_canvas = tk.Canvas(self.bottom_frame, width=self.vid.width, height=self.vid.height)
|
||||
self.vid_canvas.grid(row=0, column=3, sticky=tk.E)
|
||||
|
||||
self.update()
|
||||
|
||||
def create_window(self):
|
||||
window = tk.Toplevel()
|
||||
e1 = tk.Entry(window)
|
||||
e1.grid(row=0, column=1)
|
||||
okVar = tk.IntVar()
|
||||
tk.Button(window,text = 'Write',command=lambda: okVar.set(1)).grid(row=1,
|
||||
column=1,
|
||||
sticky=tk.W,
|
||||
pady=4)
|
||||
#print(okVar)
|
||||
self.window.wait_variable(okVar)
|
||||
self.text_to_write = e1.get()
|
||||
#print(self.text_to_write)
|
||||
window.destroy()
|
||||
#self.window.wait_window(window)
|
||||
|
||||
|
||||
def update(self):
|
||||
# Get a frame from the video source
|
||||
if self.vid is not None:
|
||||
fingers, frame, success = self.vid.get_frame()
|
||||
if fingers is not None:
|
||||
index_finger = fingers['index']
|
||||
middle_finger = fingers['middle']
|
||||
start_stop = fingers['start_stop']
|
||||
if fingers['ninja'] != 'nothing' and self.other_gestures_flag_possible == True:
|
||||
#print('trying')
|
||||
self.create_window()
|
||||
|
||||
cv2.waitKey(10)
|
||||
self.other_gestures_flag_possible = False
|
||||
x = index_finger['x']
|
||||
y = index_finger['y']
|
||||
x, y = self.scale_points(x, y)
|
||||
self.canvas.create_text(x,y,fill="darkblue", text= self.text_to_write, tags='text',font=("Purisa", 20))
|
||||
|
||||
if start_stop == 'start':
|
||||
print('start')
|
||||
self.start_draw = True
|
||||
self.first_time = True
|
||||
self.other_gestures_flag_possible = False
|
||||
|
||||
elif start_stop == 'stop':
|
||||
print('stop')
|
||||
self.start_draw = False
|
||||
self.first_time = False
|
||||
self.other_gestures_flag_possible = True
|
||||
|
||||
if self.start_draw and index_finger['straight'] and middle_finger['straight']:
|
||||
|
||||
x = index_finger['x']
|
||||
y = index_finger['y']
|
||||
x, y = self.scale_points(x, y)
|
||||
if self.first_time == True:
|
||||
self.previous_x = x
|
||||
self.previous_y = y
|
||||
self.first_time = False
|
||||
#print("first_time")
|
||||
canvas_id = self.canvas.create_line(x, y, x + 2, y + 2, self.previous_x, self.previous_y, tags='point', width=3, fill = 'red')
|
||||
self.canvas.after(100, self.canvas.delete, canvas_id)
|
||||
#self.canvas.create_line(x, y, x+1, y+1, self.previous_x, self.previous_y, tags='point', width=3)
|
||||
self.previous_x = x
|
||||
self.previous_y = y
|
||||
|
||||
if self.start_draw and index_finger['straight'] and not middle_finger['straight']:
|
||||
|
||||
x = index_finger['x']
|
||||
y = index_finger['y']
|
||||
x, y = self.scale_points(x, y)
|
||||
if self.first_time == True:
|
||||
self.previous_x = x
|
||||
self.previous_y = y
|
||||
self.first_time = False
|
||||
#print("first_time")
|
||||
self.canvas.create_line(x, y, x+1, y+1, self.previous_x, self.previous_y, tags='point', width=3)
|
||||
|
||||
self.previous_x = x
|
||||
self.previous_y = y
|
||||
if success:
|
||||
self.photo = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame))
|
||||
self.vid_canvas.create_image(0, 0, image=self.photo, anchor=tk.NW)
|
||||
|
||||
self.window.after(self.delay, self.update)
|
||||
|
||||
def back_to_projects_view(self):
|
||||
self.main_view_controller.show_frame(PROJECTS_VIEW_NAME)
|
||||
self.vid.release()
|
||||
self.destroy_widgets()
|
||||
|
||||
def clear_canvas(self):
|
||||
self.canvas.delete('all')
|
||||
|
||||
def save(self):
|
||||
self.canvas.postscript(file='image.eps')
|
||||
img = PIL.Image.open('image.eps')
|
||||
img.save('image.png', 'png')
|
||||
os.remove('image.eps')
|
||||
|
||||
def destroy_widgets(self):
|
||||
self.vid = None
|
||||
self.top_frame.destroy()
|
||||
self.canvas.destroy()
|
||||
self.bottom_frame.destroy()
|
||||
self.vid_canvas.destroy()
|
||||
self.back_button.destroy()
|
||||
|
||||
def scale_points(self, x, y):
|
||||
return x*self.canvas_width, y*self.canvas_height
|
50
client/views/projects_add_view.py
Normal file
50
client/views/projects_add_view.py
Normal file
@ -0,0 +1,50 @@
|
||||
import requests
|
||||
import tkinter as tk
|
||||
|
||||
from constants import FONT, URL_PROJECTS, PROJECTS_ADD_VIEW_NAME, PROJECTS_VIEW_NAME
|
||||
from views.abstract_view import AbstractView
|
||||
|
||||
|
||||
class ProjectsAddView(tk.Frame, AbstractView):
|
||||
|
||||
def __init__(self, parent, controller, main_view_controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
self.token = ''
|
||||
|
||||
label0 = tk.Label(self, text='Project name:', font=FONT)
|
||||
label0.pack()
|
||||
|
||||
input0 = tk.Entry(self)
|
||||
input0.pack()
|
||||
|
||||
button_add = tk.Button(self, text="Confirm and add", font=FONT,
|
||||
command=lambda: self.add_project(main_view_controller, input0.get()))
|
||||
button_add.pack()
|
||||
|
||||
button_back = tk.Button(self, text="Back", font=FONT,
|
||||
command=lambda: main_view_controller.show_frame(PROJECTS_VIEW_NAME))
|
||||
button_back.pack()
|
||||
|
||||
@staticmethod
|
||||
def get_view_name() -> str:
|
||||
return PROJECTS_ADD_VIEW_NAME
|
||||
|
||||
def start(self):
|
||||
print("ok")
|
||||
|
||||
def add_project(self, controller, project_name):
|
||||
headers = {'Authorization': 'Bearer ' + self.token}
|
||||
data = {
|
||||
"name": str(project_name)
|
||||
}
|
||||
print(data)
|
||||
response = requests.post(URL_PROJECTS, json=data, headers=headers)
|
||||
print(response)
|
||||
if response.status_code == 201:
|
||||
response = response.json()
|
||||
controller.show_frame(PROJECTS_VIEW_NAME)
|
||||
else:
|
||||
print("sth wrong")
|
||||
bad_pass_label = tk.Label(self, text='Something went wrong!', font=FONT)
|
||||
bad_pass_label.pack()
|
||||
return ()
|
44
client/views/projects_view.py
Normal file
44
client/views/projects_view.py
Normal file
@ -0,0 +1,44 @@
|
||||
import requests
|
||||
import tkinter as tk
|
||||
|
||||
from constants import FONT, FONT_LARGE, URL_PROJECTS, PROJECTS_VIEW_NAME, PROJECTS_ADD_VIEW_NAME, PROJECT_VIEW_NAME, \
|
||||
MAIN_VIEW_NAME
|
||||
from views.abstract_view import AbstractView
|
||||
|
||||
|
||||
class ProjectsView(tk.Frame, AbstractView):
|
||||
|
||||
def __init__(self, parent, controller, main_view_controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
self.token = ''
|
||||
self.projects_buttons = []
|
||||
self.main_view_controller = main_view_controller
|
||||
label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE)
|
||||
label.pack(pady=10, padx=10)
|
||||
button_add = tk.Button(self, text="Add project", font=FONT,
|
||||
command=lambda: self.main_view_controller.show_frame(PROJECTS_ADD_VIEW_NAME))
|
||||
button_add.pack()
|
||||
|
||||
button_back = tk.Button(self, text="Back", font=FONT,
|
||||
command=lambda: controller.show_frame(MAIN_VIEW_NAME, self.token))
|
||||
button_back.pack()
|
||||
label0 = tk.Label(self, text='Projects:', font=FONT)
|
||||
label0.pack()
|
||||
|
||||
@staticmethod
|
||||
def get_view_name() -> str:
|
||||
return PROJECTS_VIEW_NAME
|
||||
|
||||
def start(self):
|
||||
for button in self.projects_buttons:
|
||||
button.destroy()
|
||||
self.projects_buttons = []
|
||||
headers = {'Authorization': 'Bearer ' + self.token}
|
||||
resp = requests.get(URL_PROJECTS, headers=headers)
|
||||
response = resp.json()
|
||||
print(response)
|
||||
for projects in response:
|
||||
button_proj = tk.Button(self, text=projects['name'], font=FONT,
|
||||
command=lambda: self.main_view_controller.show_frame(PROJECT_VIEW_NAME))
|
||||
button_proj.pack()
|
||||
self.projects_buttons.append(button_proj)
|
79
client/views/register_view.py
Normal file
79
client/views/register_view.py
Normal file
@ -0,0 +1,79 @@
|
||||
import requests
|
||||
import tkinter as tk
|
||||
|
||||
from constants import FONT, FONT_LARGE, URL_REGISTER, REGISTER_VIEW_NAME, LOGIN_VIEW_NAME
|
||||
from views.abstract_view import AbstractView
|
||||
|
||||
|
||||
class RegisterView(tk.Frame, AbstractView):
|
||||
|
||||
def __init__(self, parent, controller):
|
||||
tk.Frame.__init__(self, parent)
|
||||
label = tk.Label(self, text="SmartPicasso", font=FONT_LARGE)
|
||||
label.pack(pady=10, padx=10)
|
||||
label_u = tk.Label(self, text="Register", font=FONT)
|
||||
label_u.pack(pady=10, padx=10)
|
||||
|
||||
label0 = tk.Label(self, text='Email:', font=FONT)
|
||||
label0.pack()
|
||||
|
||||
input0 = tk.Entry(self)
|
||||
input0.pack()
|
||||
|
||||
label1 = tk.Label(self, text='Login:', font=FONT)
|
||||
label1.pack()
|
||||
|
||||
input1 = tk.Entry(self)
|
||||
input1.pack()
|
||||
|
||||
label2 = tk.Label(self, text='Password:', font=FONT)
|
||||
label2.pack()
|
||||
|
||||
input2 = tk.Entry(self, show="*")
|
||||
input2.pack()
|
||||
|
||||
label3 = tk.Label(self, text='First name:', font=FONT)
|
||||
label3.pack()
|
||||
|
||||
input3 = tk.Entry(self)
|
||||
input3.pack()
|
||||
|
||||
label4 = tk.Label(self, text='Last name:', font=FONT)
|
||||
label4.pack()
|
||||
|
||||
input4 = tk.Entry(self)
|
||||
input4.pack()
|
||||
|
||||
button1 = tk.Button(self, text="Register", font=FONT,
|
||||
command=lambda: self.register(controller, input0.get(), input1.get(), input2.get(),
|
||||
input3.get(), input4.get()))
|
||||
button1.pack()
|
||||
|
||||
button2 = tk.Button(self, text="Cancel", font=FONT, command=lambda: controller.show_frame(LOGIN_VIEW_NAME))
|
||||
button2.pack()
|
||||
|
||||
@staticmethod
|
||||
def get_view_name() -> str:
|
||||
return REGISTER_VIEW_NAME
|
||||
|
||||
def register(self, controller, email, login, passw, name, lastname):
|
||||
data = {
|
||||
"email": str(email),
|
||||
"password": str(passw),
|
||||
"profile": {
|
||||
"username": str(login),
|
||||
"first_name": str(name),
|
||||
"last_name": str(lastname)
|
||||
}
|
||||
}
|
||||
print(data)
|
||||
response = requests.post(URL_REGISTER, json=data)
|
||||
print(response)
|
||||
if response.status_code == 201:
|
||||
response = response.json()
|
||||
controller.show_frame(LOGIN_VIEW_NAME)
|
||||
else:
|
||||
print("sth wrong")
|
||||
bad_pass_label = tk.Label(self, text='Something went wrong!', font=FONT)
|
||||
bad_pass_label.pack()
|
||||
return ()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user