diff --git a/.gitignore b/.gitignore index 9029d3bc..dc9770b7 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,9 @@ docs/_build/ # PyBuilder target/ +# PyCharm +.idea/ + # Jupyter Notebook .ipynb_checkpoints diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 8ba5767e..00000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,93 +0,0 @@ -# Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of -experience, education, socio-economic status, nationality, personal appearance, -race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, or to ban temporarily or permanently any -contributor for other behaviors that they deem inappropriate, threatening, -offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -This Code of Conduct also applies outside the project spaces when the Project -Steward has a reasonable belief that an individual's behavior may have a -negative impact on the project or its community. - -## Conflict Resolution - -We do not believe that all conflict is bad; healthy debate and disagreement -often yield positive results. However, it is never okay to be disrespectful or -to engage in behavior that violates the project’s code of conduct. - -If you see someone violating the code of conduct, you are encouraged to address -the behavior directly with those involved. Many issues can be resolved quickly -and easily, and this gives people more control over the outcome of their -dispute. If you are unable to resolve the matter for any reason, or if the -behavior is threatening or harassing, report it. We are dedicated to providing -an environment where participants feel welcome and safe. - -Reports should be directed to *[PROJECT STEWARD NAME(s) AND EMAIL(s)]*, the -Project Steward(s) for *[PROJECT NAME]*. It is the Project Steward’s duty to -receive and address reported violations of the code of conduct. They will then -work with a committee consisting of representatives from the Open Source -Programs Office and the Google Open Source Strategy team. If for any reason you -are uncomfortable reaching out to the Project Steward, please email -opensource@google.com. - -We will investigate every complaint, but you may not receive a direct response. -We will use our discretion in determining when and how to follow up on reported -incidents, which may range from not taking action to permanent expulsion from -the project and project-sponsored spaces. We will notify the accused of the -report and provide them an opportunity to discuss it before any action is taken. -The identity of the reporter will be omitted from the details of the report -supplied to the accused. In potentially harmful situations, such as ongoing -harassment or threats to anyone's safety, we may take action without notice. - -## Attribution - -This Code of Conduct is adapted from the Contributor Covenant, version 1.4, -available at -https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/CONTRIBUTING b/CONTRIBUTING deleted file mode 100644 index 9d7656be..00000000 --- a/CONTRIBUTING +++ /dev/null @@ -1,29 +0,0 @@ -# How to Contribute - -We'd love to accept your patches and contributions to this project. There are -just a few small guidelines you need to follow. - -## Contributor License Agreement - -Contributions to this project must be accompanied by a Contributor License -Agreement (CLA). You (or your employer) retain the copyright to your -contribution; this simply gives us permission to use and redistribute your -contributions as part of the project. Head over to - to see your current agreements on file or -to sign a new one. - -You generally only need to submit a CLA once, so if you've already submitted one -(even if it was for a different project), you probably don't need to do it -again. - -## Code Reviews - -All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. Consult -[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more -information on using pull requests. - -## Community Guidelines - -This project follows -[Google's Open Source Community Guidelines](https://opensource.google/conduct/). \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..51ac0f52 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,15 @@ +# How to Contribute + +We'd love to accept your patches and contributions to this project. There are +just a few small guidelines you need to follow. + +## Code Reviews + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more +information on using pull requests. + +## Community Guidelines + +Be a decent human being, bot, or whatever. \ No newline at end of file diff --git a/README.md b/README.md index 29d86a7a..e643ab39 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Project Gameface -Project Gameface helps gamers control their mouse cursor using their head movement and facial gestures. +# Grimassist +Grimassist helps gamers control their mouse cursor using their head movement and facial gestures. diff --git a/configs/default/cursor.json b/configs/default/cursor.json index e7ebe6ec..89c21650 100644 --- a/configs/default/cursor.json +++ b/configs/default/cursor.json @@ -14,6 +14,7 @@ "tick_interval_ms": 16, "hold_trigger_ms": 500, "auto_play": false, + "enable": 1, "mouse_acceleration": false, "use_transformation_matrix": false } \ No newline at end of file diff --git a/configs/profile_1/cursor.json b/configs/profile_1/cursor.json index 2e9a023b..52c368b6 100644 --- a/configs/profile_1/cursor.json +++ b/configs/profile_1/cursor.json @@ -5,15 +5,16 @@ "tracking_vert_idxs": [ 8 ], - "spd_up": 41, - "spd_down": 41, - "spd_left": 41, - "spd_right": 41, - "pointer_smooth": 15, + "spd_up": 40, + "spd_down": 40, + "spd_left": 40, + "spd_right": 40, + "pointer_smooth": 6, "shape_smooth": 10, "tick_interval_ms": 16, "hold_trigger_ms": 500, "auto_play": false, - "mouse_acceleration": false, + "enable": 1, + "mouse_acceleration": false, "use_transformation_matrix": false } \ No newline at end of file diff --git a/configs/profile_2/cursor.json b/configs/profile_2/cursor.json index 69bd284f..e53fadec 100644 --- a/configs/profile_2/cursor.json +++ b/configs/profile_2/cursor.json @@ -14,6 +14,7 @@ "tick_interval_ms": 16, "hold_trigger_ms": 500, "auto_play": false, + "enable": 1, "mouse_acceleration": false, "use_transformation_matrix": false } \ No newline at end of file diff --git a/src/accel_graph.py b/src/accel_graph.py index c60748a4..8709ec94 100644 --- a/src/accel_graph.py +++ b/src/accel_graph.py @@ -1,17 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - import abc import math diff --git a/src/camera_manager.py b/src/camera_manager.py index cdf3fcc4..e9ea8534 100644 --- a/src/camera_manager.py +++ b/src/camera_manager.py @@ -1,17 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - import concurrent.futures as futures import logging import threading @@ -25,7 +11,7 @@ import src.utils as utils from src.config_manager import ConfigManager -from src.controllers import MouseController +from src.controllers import Keybinder from src.singleton_meta import Singleton MAX_SEARCH_CAMS = 5 @@ -123,7 +109,7 @@ def draw_overlay(self, track_loc): self.frame_buffers["debug"] = self.frame_buffers["raw"].copy() # Disabled - if not MouseController().is_active.get(): + if not Keybinder().is_active.get(): self.frame_buffers["debug"] = add_overlay( self.frame_buffers["debug"], self.overlay_disabled, 0, 0, 640, 108) diff --git a/src/config_manager.py b/src/config_manager.py index cbfd5a84..d6f6247d 100644 --- a/src/config_manager.py +++ b/src/config_manager.py @@ -1,17 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - import copy import json import logging diff --git a/src/controllers/__init__.py b/src/controllers/__init__.py index 4f5d8c10..28537d01 100644 --- a/src/controllers/__init__.py +++ b/src/controllers/__init__.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. from .keybinder import * from .mouse_controller import * diff --git a/src/controllers/keybinder.py b/src/controllers/keybinder.py index e3a6c38d..54a904a7 100644 --- a/src/controllers/keybinder.py +++ b/src/controllers/keybinder.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import copy import logging @@ -19,10 +6,10 @@ import pydirectinput import win32api +import tkinter as tk import src.shape_list as shape_list from src.config_manager import ConfigManager -from src.controllers.mouse_controller import MouseController from src.singleton_meta import Singleton logger = logging.getLogger("Keybinder") @@ -42,6 +29,7 @@ def __init__(self) -> None: self.holding = False self.is_started = False self.last_know_keybinds = {} + self.is_active = None def start(self): if not self.is_started: @@ -51,6 +39,9 @@ def start(self): self.monitors = self.get_monitors() self.is_started = True + self.is_active = tk.BooleanVar() + self.is_active.set(ConfigManager().config["auto_play"]) + def init_states(self) -> None: """Re initializes the state of the keybinder. If new keybinds are added. @@ -177,13 +168,13 @@ def act(self, blendshape_values) -> dict: if mon_id is None: return - MouseController().toggle_active() + self.toggle_active() self.key_states[state_name] = True elif (val < thres) and (self.key_states[state_name] is True): self.key_states[state_name] = False - elif MouseController().is_active.get(): + elif self.is_active.get(): if device == "mouse": @@ -223,6 +214,16 @@ def act(self, blendshape_values) -> dict: elif device == "keyboard": self.keyboard_action(val, action, thres, mode) + def set_active(self, flag: bool) -> None: + self.is_active.set(flag) + if flag: + self.delay_count = 0 + + def toggle_active(self): + logging.info("Toggle active") + curr_state = self.is_active.get() + self.set_active(not curr_state) + def destroy(self): """Destroy the keybinder""" return diff --git a/src/controllers/mouse_controller.py b/src/controllers/mouse_controller.py index 25bafd15..22c608b4 100644 --- a/src/controllers/mouse_controller.py +++ b/src/controllers/mouse_controller.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import concurrent.futures as futures import logging import threading @@ -48,7 +35,8 @@ def __init__(self): self.is_started = False self.is_destroyed = False self.stop_flag = None - self.is_active = None + self.is_active = tk.BooleanVar() + self.is_enabled = None def start(self): if not self.is_started: @@ -60,8 +48,8 @@ def start(self): self.screen_w, self.screen_h = pyautogui.size() self.calc_smooth_kernel() - self.is_active = tk.BooleanVar() - self.is_active.set(ConfigManager().config["auto_play"]) + self.is_enabled = tk.BooleanVar() + self.is_enabled.set(ConfigManager().config["enable"]) self.stop_flag = threading.Event() self.pool.submit(self.main_loop) @@ -102,7 +90,7 @@ def main_loop(self) -> None: return while not self.stop_flag.is_set(): - if not self.is_active.get(): + if not self.is_active.get() or not self.is_enabled.get(): time.sleep(0.001) continue @@ -136,6 +124,11 @@ def main_loop(self) -> None: time.sleep(ConfigManager().config["tick_interval_ms"] / 1000) + def set_enabled(self, flag: bool) -> None: + self.is_enabled.set(flag) + if flag: + self.delay_count = 0 + def set_active(self, flag: bool) -> None: self.is_active.set(flag) if flag: diff --git a/src/detectors/__init__.py b/src/detectors/__init__.py index 688689dc..d573beb2 100644 --- a/src/detectors/__init__.py +++ b/src/detectors/__init__.py @@ -1,15 +1,2 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. from .facemesh import * diff --git a/src/detectors/facemesh.py b/src/detectors/facemesh.py index c974a767..5f61f329 100644 --- a/src/detectors/facemesh.py +++ b/src/detectors/facemesh.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging import time diff --git a/src/gui/__init__.py b/src/gui/__init__.py index 3d280881..0fb4001e 100644 --- a/src/gui/__init__.py +++ b/src/gui/__init__.py @@ -1,15 +1,2 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. from .main_gui import * diff --git a/src/gui/balloon.py b/src/gui/balloon.py index a2c7da15..8fa70e3d 100644 --- a/src/gui/balloon.py +++ b/src/gui/balloon.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. from functools import partial diff --git a/src/gui/dropdown.py b/src/gui/dropdown.py index 691b46f7..bf17fa4f 100644 --- a/src/gui/dropdown.py +++ b/src/gui/dropdown.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. from functools import partial diff --git a/src/gui/frames/__init__.py b/src/gui/frames/__init__.py index 3fc7740c..dfcf2080 100644 --- a/src/gui/frames/__init__.py +++ b/src/gui/frames/__init__.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. from .frame_cam_preview import * from .frame_menu import * diff --git a/src/gui/frames/frame_cam_preview.py b/src/gui/frames/frame_cam_preview.py index 6fb38be0..dba86134 100644 --- a/src/gui/frames/frame_cam_preview.py +++ b/src/gui/frames/frame_cam_preview.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import tkinter @@ -19,7 +6,7 @@ from src.camera_manager import CameraManager from src.config_manager import ConfigManager -from src.controllers import MouseController +from src.controllers import Keybinder from src.gui.frames.safe_disposable_frame import SafeDisposableFrame CANVAS_WIDTH = 216 @@ -72,7 +59,7 @@ def __init__(self, master, master_callback: callable, **kwargs): border_color="transparent", switch_height=18, switch_width=32, - variable=MouseController().is_active, + variable=Keybinder().is_active, command=lambda: master_callback( "toggle_switch", {"switch_status": self.toggle_switch.get()}), onvalue=1, @@ -87,7 +74,7 @@ def __init__(self, master, master_callback: callable, **kwargs): pady=5, sticky="nw") - # Toggle label + # Toggle description label self.toggle_label = customtkinter.CTkLabel( master=self, compound='right', diff --git a/src/gui/frames/frame_menu.py b/src/gui/frames/frame_menu.py index 404d3e49..a3df5ede 100644 --- a/src/gui/frames/frame_menu.py +++ b/src/gui/frames/frame_menu.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. from functools import partial diff --git a/src/gui/frames/frame_profile.py b/src/gui/frames/frame_profile.py index a5285b89..7bc2131f 100644 --- a/src/gui/frames/frame_profile.py +++ b/src/gui/frames/frame_profile.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import time import logging diff --git a/src/gui/frames/frame_profile_editor.py b/src/gui/frames/frame_profile_editor.py index 2ab26b67..cbce285c 100644 --- a/src/gui/frames/frame_profile_editor.py +++ b/src/gui/frames/frame_profile_editor.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging import re diff --git a/src/gui/frames/frame_profile_switcher.py b/src/gui/frames/frame_profile_switcher.py index 7fa7fbe8..a8da1b8c 100644 --- a/src/gui/frames/frame_profile_switcher.py +++ b/src/gui/frames/frame_profile_switcher.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging import re diff --git a/src/gui/frames/safe_disposable_frame.py b/src/gui/frames/safe_disposable_frame.py index 8e2e5b00..cc464ad0 100644 --- a/src/gui/frames/safe_disposable_frame.py +++ b/src/gui/frames/safe_disposable_frame.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging diff --git a/src/gui/main_gui.py b/src/gui/main_gui.py index ff052b7c..3acccb9f 100644 --- a/src/gui/main_gui.py +++ b/src/gui/main_gui.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging import tkinter as tk @@ -21,7 +8,7 @@ import src.gui.frames as frames import src.gui.pages as pages from src.config_manager import ConfigManager -from src.controllers import MouseController +from src.controllers import Keybinder, MouseController customtkinter.set_appearance_mode("light") customtkinter.set_default_color_theme("assets/themes/google_theme.json") @@ -37,7 +24,7 @@ def __init__(self, tk_root): self.tk_root = tk_root self.tk_root.geometry("1024x658") - self.tk_root.title(f"Project Gameface {ConfigManager().version}") + self.tk_root.title(f"Grimassist {ConfigManager().version}") self.tk_root.iconbitmap("assets/images/icon.ico") self.tk_root.resizable(width=False, height=False) @@ -154,10 +141,13 @@ def cam_preview_callback(self, function_name, args: dict, **kwargs): if function_name == "toggle_switch": self.set_mediapipe_mouse_enable(new_state=args["switch_status"]) + def set_mediapipe_mouse_enable(self, new_state: bool): if new_state: + Keybinder().set_active(True) MouseController().set_active(True) else: + Keybinder().set_active(False) MouseController().set_active(False) def change_page(self, target_page_name: str): diff --git a/src/gui/pages/__init__.py b/src/gui/pages/__init__.py index 7b578760..0a10c0e0 100644 --- a/src/gui/pages/__init__.py +++ b/src/gui/pages/__init__.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. from .page_cursor import * from .page_home import * diff --git a/src/gui/pages/page_cursor.py b/src/gui/pages/page_cursor.py index 20c4466c..27a7c847 100644 --- a/src/gui/pages/page_cursor.py +++ b/src/gui/pages/page_cursor.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging import tkinter @@ -21,7 +8,7 @@ from PIL import Image from src.config_manager import ConfigManager -from src.controllers import MouseController +from src.controllers import MouseController, Keybinder from src.gui.balloon import Balloon from src.gui.frames.safe_disposable_frame import SafeDisposableFrame @@ -71,9 +58,44 @@ def __init__( 1, MAX_HOLD_TRIG ] }) - + # Toggle label + self.toggle_label = customtkinter.CTkLabel(master=self, + compound='right', + text="Cursor control", + justify=tkinter.RIGHT) + self.toggle_label.cget("font").configure(weight='bold') + self.toggle_label.grid(row=0, + column=0, + padx=(20, 0), + pady=5, + sticky="nw") + + # Toggle switch + self.toggle_switch = customtkinter.CTkSwitch( + master=self, + text="", + width=20, + border_color="transparent", + switch_height=18, + switch_width=32, + command=lambda: self.cursor_toggle_callback( + "toggle_switch", {"switch_status": self.toggle_switch.get()}), + variable=MouseController().is_enabled, + onvalue=1, + offvalue=0, + ) + if ConfigManager().config["enable"]: + self.toggle_switch.select() + + self.toggle_switch.grid(row=0, + column=0, + padx=(150, 0), + pady=5, + sticky="nw") self.load_initial_config() + + def load_initial_config(self): """Load default from config and set the UI """ @@ -105,7 +127,7 @@ def create_divs(self, directions: dict): text=show_name, justify=tkinter.LEFT) label.cget("font").configure(weight='bold') - label.grid(row=idx, column=0, padx=20, pady=(10, 10), sticky="nw") + label.grid(row=idx+2, column=0, padx=20, pady=(10, 10), sticky="nw") self.shared_info_balloon.register_widget(label, balloon_text) # Slider @@ -121,7 +143,7 @@ def create_divs(self, directions: dict): partial(self.slider_mouse_down_callback, cfg_name)) slider.bind("", partial(self.slider_mouse_up_callback, cfg_name)) - slider.grid(row=idx, column=0, padx=30, pady=(40, 10), sticky="nw") + slider.grid(row=idx+2, column=0, padx=30, pady=(40, 10), sticky="nw") # Number entry entry_var = tkinter.StringVar() @@ -134,7 +156,7 @@ def create_divs(self, directions: dict): textvariable=entry_var, #validatecommand=vcmd, width=62) - entry.grid(row=idx, + entry.grid(row=idx+2, column=0, padx=(300, 5), pady=(34, 10), @@ -218,6 +240,37 @@ def slider_mouse_up_callback(self, div_name: str, event): def inner_refresh_profile(self): self.load_initial_config() + def enable_cursor(self, new_state: bool): + new={} + if new_state: + for cfg_name, div in self.divs.items(): + slider = div["slider"] + slider.configure(state="normal", fg_color="#D2E3FC", progress_color="#1A73E8", button_color="#1A73E8") + div["slider"] = slider + new.update({cfg_name: div}) + else: + for cfg_name, div in self.divs.items(): + slider = div["slider"] + slider.configure(state="disabled", fg_color="lightgray", progress_color="gray", button_color="gray") + div["slider"] = slider + new.update({cfg_name: div}) + self.divs=new + ConfigManager().set_temp_config(field="enable", value=new_state) + ConfigManager().apply_config() + + def cursor_toggle_callback(self, command, args: dict): + logger.info(f"cursor_toggle_callback {command} with {args}") + + if command == "toggle_switch": + self.enable_cursor(new_state=args["switch_status"]) + self.set_mediapipe_mouse_enable(new_state=args["switch_status"]) + + def set_mediapipe_mouse_enable(self, new_state: bool): + if new_state: + MouseController().set_enabled(True) + else: + MouseController().set_enabled(False) + class PageCursor(SafeDisposableFrame): @@ -241,7 +294,7 @@ def __init__(self, master, **kwargs): columnspan=1) # Description. - des_txt = "Mouse cursor moves with your head movement. Use this settings to adjust how fast your mouse moves in each direction." + des_txt = "Adjust how the mouse cursor responds to your head movements." des_label = customtkinter.CTkLabel(master=self, text=des_txt, wraplength=300, @@ -251,7 +304,7 @@ def __init__(self, master, **kwargs): # Inner frame self.inner_frame = FrameSelectGesture(self) - self.inner_frame.grid(row=2, column=0, padx=5, pady=5, sticky="nw") + self.inner_frame.grid(row=4, column=0, padx=5, pady=5, sticky="nw") def refresh_profile(self): self.inner_frame.inner_refresh_profile() diff --git a/src/gui/pages/page_home.py b/src/gui/pages/page_home.py index 11b071f8..20935347 100644 --- a/src/gui/pages/page_home.py +++ b/src/gui/pages/page_home.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging import tkinter @@ -39,7 +26,7 @@ def __init__(self, master, root_callback: callable, **kwargs): # Top text top_label = customtkinter.CTkLabel( - master=self, text="Project Gameface Gesture Settings") + master=self, text="Grimassist Gesture Settings") top_label.cget("font").configure(size=24) top_label.grid(row=0, column=0, @@ -49,7 +36,7 @@ def __init__(self, master, root_callback: callable, **kwargs): columnspan=2) # Description - des_txt = "Project Gameface helps gamers control their mouse cursor using their head movement and facial gestures." + des_txt = "Grimassist helps gamers control their mouse cursor using their head movement and facial gestures." des_label = customtkinter.CTkLabel(master=self, text=des_txt, wraplength=400, @@ -63,7 +50,7 @@ def __init__(self, master, root_callback: callable, **kwargs): columnspan=2) # Disclaimer - disc_txt = "Disclaimer: Project Gameface is not intended for medical use." + disc_txt = "Disclaimer: Grimassist is not intended for medical use." disc_label = customtkinter.CTkLabel(master=self, text=disc_txt, wraplength=700, diff --git a/src/gui/pages/page_keyboard.py b/src/gui/pages/page_keyboard.py index 464d2c48..7526f103 100644 --- a/src/gui/pages/page_keyboard.py +++ b/src/gui/pages/page_keyboard.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging import tkinter as tk diff --git a/src/gui/pages/page_select_camera.py b/src/gui/pages/page_select_camera.py index e718fe8c..31d92f96 100644 --- a/src/gui/pages/page_select_camera.py +++ b/src/gui/pages/page_select_camera.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging import tkinter diff --git a/src/gui/pages/page_select_gestures.py b/src/gui/pages/page_select_gestures.py index 2a070987..f7b5f125 100644 --- a/src/gui/pages/page_select_gestures.py +++ b/src/gui/pages/page_select_gestures.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import tkinter as tk from functools import partial diff --git a/src/pipeline.py b/src/pipeline.py index 97b0f6b4..582573e0 100644 --- a/src/pipeline.py +++ b/src/pipeline.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging from src.camera_manager import CameraManager diff --git a/src/singleton_meta.py b/src/singleton_meta.py index 7b27edfc..7ecf26d6 100644 --- a/src/singleton_meta.py +++ b/src/singleton_meta.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. class Singleton(type): diff --git a/src/task_killer.py b/src/task_killer.py index 57407c30..48b12e4b 100644 --- a/src/task_killer.py +++ b/src/task_killer.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import logging import os diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 07b7fe3d..4e3640e3 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. from .install_font import * from .list_cameras import * diff --git a/src/utils/install_font.py b/src/utils/install_font.py index 4c7a737a..9fe998d0 100644 --- a/src/utils/install_font.py +++ b/src/utils/install_font.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import ctypes import logging diff --git a/src/utils/list_cameras.py b/src/utils/list_cameras.py index 193dc465..f9ec06cc 100644 --- a/src/utils/list_cameras.py +++ b/src/utils/list_cameras.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import concurrent.futures as futures import logging diff --git a/src/utils/smoothing.py b/src/utils/smoothing.py index 35a2e6b0..613522b4 100644 --- a/src/utils/smoothing.py +++ b/src/utils/smoothing.py @@ -1,16 +1,3 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. import numpy as np import numpy.typing as npt