-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: improve autoclick functionality and UI feedback
- Refactored `autoclick.py` to use the `textual` library for a better UI experience. - Added real-time status updates with dynamic background color changes based on autoclicker state. - Updated `click_mouse.py` to support status callbacks for UI integration.
- Loading branch information
Showing
3 changed files
with
86 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,57 @@ | ||
# !/usr/bin/python | ||
from click_mouse import * | ||
from textual.app import App, ComposeResult | ||
from textual.widgets import Static | ||
from textual.reactive import reactive | ||
from pynput.keyboard import Listener, KeyCode | ||
from pynput.mouse import Button, Controller | ||
from rich.console import Console | ||
from rich.style import Style | ||
import argparse | ||
import os | ||
from click_mouse import ClickMouse | ||
from textual.color import Color | ||
|
||
console = Console() | ||
|
||
parser = argparse.ArgumentParser(description="Autoclicker") | ||
parser.add_argument("--left", action="store_true", help="Use left mouse button") | ||
parser.add_argument("--right", action="store_true", help="Use right mouse button") | ||
args = parser.parse_args() | ||
class AutoClickApp(App): | ||
CSS = "Screen {align: center middle;}" | ||
status = reactive("[white]Autoclick: STOPPED[/white]") | ||
|
||
delay: float = 0.1 | ||
button = Button.left | ||
def __init__(self, delay, button): | ||
super().__init__() | ||
self.delay = delay | ||
self.button = button | ||
self.click_thread = ClickMouse(delay, button, self.update_status) | ||
self.listener = None | ||
|
||
if args.left: | ||
button = Button.left | ||
delay: float = 0.05 | ||
elif args.right: | ||
button = Button.right | ||
delay: float = 0.5 | ||
def compose(self) -> ComposeResult: | ||
self.status_display = Static(self.status) | ||
instructions = Static("[cyan]Press [bold]R[/bold] to start/stop | Press [bold]X[/bold] to exit[/cyan]") | ||
yield self.status_display | ||
yield instructions | ||
|
||
|
||
os.system('cls' if os.name == 'nt' else 'clear') | ||
console.print("PRESS 'r'", style="#aaaaaa", justify="center", ) | ||
start_stop_key = KeyCode(char='r') | ||
exit_key = KeyCode(char='x') | ||
|
||
|
||
click_thread = ClickMouse(delay, button) | ||
click_thread.start() | ||
|
||
|
||
def on_press(key): | ||
if key == start_stop_key: | ||
if click_thread.running: | ||
click_thread.stop_clicking() | ||
console.print("stop autoclick", style="#ffffff") | ||
def update_status(self, message): | ||
self.status = message | ||
if "RUNNING" in message: | ||
self.screen.styles.background = Color(78, 191, 96) | ||
else: | ||
style = Style(bgcolor="#eeeeee", color="#3322dd") | ||
click_thread.start_clicking() | ||
console.print("start autoclick", style=style) | ||
elif key == exit_key: | ||
console.print("exit autoclick", style="#aaaaaa") | ||
click_thread.exit() | ||
listener.stop() | ||
|
||
|
||
|
||
with Listener(on_press=on_press) as listener: | ||
listener.join() | ||
self.screen.styles.background = Color(191, 78, 96) | ||
|
||
|
||
def on_mount(self) -> None: | ||
self.screen.styles.background = Color(191, 78, 96) | ||
self.screen.styles.border = ('heavy', 'white') | ||
self.click_thread.start() | ||
start_stop_key = KeyCode(char='r') | ||
exit_key = KeyCode(char='x') | ||
|
||
def on_press(key): | ||
if key == start_stop_key: | ||
if self.click_thread.running: | ||
self.click_thread.stop_clicking() | ||
else: | ||
self.click_thread.start_clicking() | ||
elif key == exit_key: | ||
self.exit() | ||
|
||
self.listener = Listener(on_press=on_press) | ||
self.listener.start() | ||
|
||
def on_unmount(self) -> None: | ||
if self.listener: | ||
self.listener.stop() | ||
self.click_thread.exit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,35 @@ | ||
import time | ||
import threading | ||
import time | ||
from pynput.mouse import Controller, Button | ||
from enum import Enum | ||
|
||
mouse = Controller() | ||
|
||
class ClickMouse(threading.Thread): | ||
def __init__(self, delay, button): | ||
super(ClickMouse, self).__init__() | ||
def __init__(self, delay, button, update_status_callback): | ||
super().__init__() | ||
self.delay = delay | ||
self.button = button | ||
self.button = Button.left if button == 'left' else Button.right | ||
self.update_status_callback = update_status_callback | ||
self.running = False | ||
self.program_running = True | ||
self.mouse = Controller() | ||
self.daemon = True | ||
|
||
def start_clicking(self): | ||
self.running = True | ||
self.update_status_callback("[green]Autoclick: RUNNING[/green]") | ||
|
||
def stop_clicking(self): | ||
self.running = False | ||
self.update_status_callback("[yellow]Autoclick: STOPPED[/yellow]") | ||
|
||
def exit(self): | ||
self.stop_clicking() | ||
self.program_running = False | ||
|
||
def run(self): | ||
while self.program_running: | ||
while self.running: | ||
mouse.click(self.button) | ||
if self.running: | ||
self.mouse.click(self.button) | ||
time.sleep(self.delay) | ||
time.sleep(0.1) | ||
else: | ||
time.sleep(0.1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from pynput.mouse import Button | ||
import argparse | ||
import os | ||
from autoclick import AutoClickApp | ||
|
||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser(description="Autoclicker with Textual") | ||
parser.add_argument("--left", action="store_true", help="Use left mouse button") | ||
parser.add_argument("--right", action="store_true", help="Use right mouse button") | ||
args = parser.parse_args() | ||
|
||
delay = 0.1 | ||
button = Button.left | ||
|
||
if args.left: | ||
button = Button.left | ||
delay = 0.05 | ||
elif args.right: | ||
button = Button.right | ||
delay = 0.5 | ||
|
||
os.system('cls' if os.name == 'nt' else 'clear') | ||
app = AutoClickApp(delay, button) | ||
app.run() |