133 lines
4.3 KiB
Python
133 lines
4.3 KiB
Python
import flet as ft
|
|
import pyperclip
|
|
import time
|
|
import threading
|
|
import os
|
|
|
|
def main(page: ft.Page):
|
|
# --- 1. Window Configuration ---
|
|
page.title = "PathWarp"
|
|
page.theme_mode = ft.ThemeMode.DARK
|
|
page.window.width = 320
|
|
page.window.height = 360
|
|
page.window.resizable = False
|
|
page.window.always_on_top = True
|
|
page.padding = 10
|
|
page.spacing = 10
|
|
|
|
# Center the window on startup
|
|
page.window.center()
|
|
|
|
# Set Window Icon
|
|
if os.path.exists("logo.ico"):
|
|
page.window.icon = "logo.ico"
|
|
|
|
# --- 2. Path Conversion Logic ---
|
|
def do_convert(win_path):
|
|
if not win_path: return None
|
|
p = win_path.strip().strip('"').strip("'")
|
|
if p.lower().startswith("w:"):
|
|
rel = p[2:].lstrip("\\")
|
|
# Your Samba mapping: W:\ -> /home/rongye/ProgramFiles/
|
|
return f"/home/rongye/ProgramFiles/{rel.replace('\\', '/')}"
|
|
return None
|
|
|
|
# --- 3. UI Components ---
|
|
input_field = ft.TextField(
|
|
label="Windows Path",
|
|
hint_text=r"e.g. W:\Project\Main",
|
|
text_size=12,
|
|
height=45,
|
|
border_color=ft.Colors.CYAN_800,
|
|
prefix_icon=ft.Icons.FOLDER_OPEN,
|
|
content_padding=10,
|
|
)
|
|
|
|
result_field = ft.TextField(
|
|
label="Ubuntu Path",
|
|
read_only=True,
|
|
text_size=12,
|
|
height=45,
|
|
color=ft.Colors.GREEN_400,
|
|
border_color=ft.Colors.GREEN_900,
|
|
prefix_icon=ft.Icons.TERMINAL,
|
|
content_padding=10,
|
|
)
|
|
|
|
status_text = ft.Text("Ready", size=10, color=ft.Colors.GREY_600)
|
|
|
|
def convert_click(e):
|
|
res = do_convert(input_field.value)
|
|
if res:
|
|
result_field.value = res
|
|
pyperclip.copy(res)
|
|
status_text.value = f"Copied: {time.strftime('%H:%M:%S')}"
|
|
status_text.color = ft.Colors.GREEN_400
|
|
else:
|
|
status_text.value = "Error: Invalid Path"
|
|
status_text.color = ft.Colors.RED_400
|
|
page.update()
|
|
|
|
# --- 4. Background Clipboard Monitor ---
|
|
stop_listen = threading.Event()
|
|
def listen_clip():
|
|
last_clip = ""
|
|
while not stop_listen.is_set():
|
|
try:
|
|
curr = pyperclip.paste().strip().strip('"')
|
|
if curr != last_clip and curr.lower().startswith("w:"):
|
|
conv = do_convert(curr)
|
|
if conv:
|
|
pyperclip.copy(conv)
|
|
input_field.value = curr
|
|
result_field.value = conv
|
|
status_text.value = "Auto-Warped"
|
|
status_text.color = ft.Colors.CYAN_400
|
|
last_clip = conv
|
|
page.update()
|
|
except: pass
|
|
time.sleep(0.5)
|
|
|
|
def toggle_listen(e):
|
|
if listen_switch.value:
|
|
stop_listen.clear()
|
|
threading.Thread(target=listen_clip, daemon=True).start()
|
|
status_text.value = "Monitoring..."
|
|
else:
|
|
stop_listen.set()
|
|
status_text.value = "Stopped"
|
|
page.update()
|
|
|
|
listen_switch = ft.Switch(label="Auto Monitor", value=False, on_change=toggle_listen, scale=0.7)
|
|
|
|
# --- 5. Compact Layout ---
|
|
page.add(
|
|
ft.Column([
|
|
ft.Row([
|
|
ft.Icon(ft.Icons.BOLT, color=ft.Colors.CYAN_400, size=18),
|
|
ft.Text("PathWarp", size=16, weight=ft.FontWeight.BOLD),
|
|
], alignment=ft.MainAxisAlignment.CENTER),
|
|
|
|
input_field,
|
|
|
|
ft.FilledButton(
|
|
"Convert & Copy",
|
|
on_click=convert_click,
|
|
width=320,
|
|
height=40,
|
|
style=ft.ButtonStyle(shape=ft.RoundedRectangleBorder(radius=6)),
|
|
),
|
|
|
|
result_field,
|
|
|
|
ft.Container(
|
|
content=ft.Row([listen_switch, status_text], alignment=ft.MainAxisAlignment.SPACE_BETWEEN),
|
|
padding=ft.padding.only(left=5, right=10),
|
|
bgcolor=ft.Colors.BLACK12,
|
|
border_radius=5,
|
|
)
|
|
], spacing=8)
|
|
)
|
|
|
|
if __name__ == "__main__":
|
|
ft.app(target=main) |