Untitled
unknown
plain_text
a year ago
14 kB
4
Indexable
class TouchKeyboard(ctk.CTkFrame):
def __init__(self, parent, entry_widget, dark_mode=False):
super().__init__(parent)
self.entry_widget = entry_widget
self.dark_mode = dark_mode
self.shift_mode = False
self.special_chars_mode = False
# Define keyboard layouts
self.normal_layout = [
"1234567890",
"qwertzuiop",
"asdfghjkl",
"yxcvbnm",
]
self.shift_layout = [
"1234567890",
"QWERTZUIOP",
"ASDFGHJKL",
"YXCVBNM",
]
self.special_layout = [
"!@#$%^&*()",
"äöüß-_+:;",
",.<>/?\'\"",
"\\|[]{}",
]
# Current layout starts with normal
self.current_layout = self.normal_layout
# Button styling
self.button_style = {
"height": 45,
"corner_radius": 8,
"fg_color": '#2c2c2e' if dark_mode else '#e5e5e7',
"hover_color": '#3a3a3c' if dark_mode else '#d1d1d6',
"text_color": 'white' if dark_mode else 'black',
"font": ("Helvetica", 16)
}
self.create_keyboard()
def create_keyboard(self):
# Main keyboard container with padding
keyboard_container = ctk.CTkFrame(self, fg_color="transparent")
keyboard_container.pack(padx=20, pady=20)
# Create rows for each line of keys
for row in self.current_layout:
row_frame = ctk.CTkFrame(keyboard_container, fg_color="transparent")
row_frame.pack(pady=4)
# Calculate button width based on row length
button_width = min(55, 460 // len(row))
for char in row:
btn = ctk.CTkButton(
row_frame,
text=char,
width=button_width,
command=lambda c=char: self.button_click(c),
**self.button_style
)
btn.pack(side="left", padx=2)
# Create bottom row with special keys
bottom_frame = ctk.CTkFrame(keyboard_container, fg_color="transparent")
bottom_frame.pack(pady=4)
# Special characters toggle
special_btn = ctk.CTkButton(
bottom_frame,
text="!#$",
width=70,
command=self.toggle_special,
**self.button_style
)
special_btn.pack(side="left", padx=2)
# Shift key
self.shift_btn = ctk.CTkButton(
bottom_frame,
text="⇧",
width=70,
command=self.toggle_shift,
**self.button_style
)
self.shift_btn.pack(side="left", padx=2)
# Space bar
space_btn = ctk.CTkButton(
bottom_frame,
text="Space",
width=180,
command=lambda: self.button_click(" "),
**self.button_style
)
space_btn.pack(side="left", padx=2)
# Backspace key
backspace_btn = ctk.CTkButton(
bottom_frame,
text="←",
width=70,
command=self.backspace,
**self.button_style
)
backspace_btn.pack(side="left", padx=2)
# Enter key
enter_btn = ctk.CTkButton(
bottom_frame,
text="✓",
width=70,
command=self.enter_click,
fg_color='#34c759',
hover_color='#30d158',
text_color='white',
height=45,
corner_radius=8,
font=("Helvetica", 16)
)
enter_btn.pack(side="left", padx=2)
def rebuild_keyboard(self):
# Destroy all existing widgets
for widget in self.winfo_children():
widget.destroy()
# Rebuild with current layout
self.create_keyboard()
def toggle_shift(self):
self.shift_mode = not self.shift_mode
self.special_chars_mode = False
self.current_layout = self.shift_layout if self.shift_mode else self.normal_layout
self.rebuild_keyboard()
def toggle_special(self):
self.special_chars_mode = not self.special_chars_mode
self.shift_mode = False
self.current_layout = self.special_layout if self.special_chars_mode else self.normal_layout
self.rebuild_keyboard()
def button_click(self, char):
current = self.entry_widget.get()
self.entry_widget.delete(0, ctk.END)
self.entry_widget.insert(0, current + char)
# If shift is on, turn it off after one character
if self.shift_mode:
self.toggle_shift()
def backspace(self):
current = self.entry_widget.get()
if current:
self.entry_widget.delete(len(current) - 1)
def enter_click(self):
self.event_generate("<<KeyboardEnter>>")
class PasswordEntryScreen(ctk.CTkFrame):
def __init__(self, parent, network_name, dark_mode: bool, language: str, callback):
super().__init__(
parent,
fg_color='#1c1c1e' if dark_mode else '#f5f5f7',
width=1024,
height=600
)
self.parent = parent
self.dark_mode = dark_mode
self.network_name = network_name
self.language = language
self.callback = callback
# Create main container
self.container = ctk.CTkFrame(
self,
fg_color='transparent',
corner_radius=0
)
self.container.pack(fill='both', expand=True, padx=40, pady=40)
# Create centered content frame
self.content_frame = ctk.CTkFrame(
self.container,
fg_color='#2c2c2e' if dark_mode else '#e5e5e7',
corner_radius=15
)
self.content_frame.pack(expand=True, fill='both')
# Header with network name
header_frame = ctk.CTkFrame(
self.content_frame,
fg_color='transparent'
)
header_frame.pack(fill='x', padx=20, pady=(20, 0))
# Back button
back_btn = ctk.CTkButton(
header_frame,
text="←",
width=40,
command=self.destroy,
fg_color='#3a3a3c' if dark_mode else '#d1d1d6',
hover_color='#4a4a4c' if dark_mode else '#c1c1c6',
text_color='white' if dark_mode else 'black'
)
back_btn.pack(side='left')
# Network name
network_label = ctk.CTkLabel(
header_frame,
text=network_name,
font=("Helvetica", 20, "bold"),
text_color='white' if dark_mode else 'black'
)
network_label.pack(side='left', padx=20)
# Password entry
self.password_frame = ctk.CTkFrame(
self.content_frame,
fg_color='transparent'
)
self.password_frame.pack(fill='x', padx=20, pady=20)
self.password_entry = ctk.CTkEntry(
self.password_frame,
placeholder_text="Password",
font=("Helvetica", 16),
height=45,
show="•"
)
self.password_entry.pack(fill='x')
# Add keyboard
self.keyboard = TouchKeyboard(
self.content_frame,
self.password_entry,
dark_mode
)
self.keyboard.pack(pady=20)
# Bind keyboard enter event
self.bind("<<KeyboardEnter>>", self.handle_connect)
def handle_connect(self, event=None):
password = self.password_entry.get()
if password:
self.callback(self.network_name, password)
self.destroy()
class WiFiScreen(ctk.CTkFrame):
def __init__(self, parent, dark_mode: bool, language: str):
super().__init__(
parent,
fg_color='#1c1c1e' if dark_mode else '#f5f5f7',
width=1024,
height=600
)
self.parent = parent
self.dark_mode = dark_mode
self.language = language
self.networks = set() # Use set to store unique network names
self.scanning = False
# Create main container with padding
self.container = ctk.CTkFrame(
self,
fg_color='transparent'
)
self.container.pack(fill='both', expand=True, padx=30, pady=30)
# Create header
self.create_header()
# Create scrollable content area
self.scrollable_frame = ctk.CTkScrollableFrame(
self.container,
fg_color='transparent',
height=450
)
self.scrollable_frame.pack(fill='x', pady=(20, 0))
# Start network scan
self.scan_networks()
def create_header(self):
header_frame = ctk.CTkFrame(
self.container,
fg_color='transparent'
)
header_frame.pack(fill='x')
# Back button
back_btn = ctk.CTkButton(
header_frame,
text="←",
width=40,
command=self.destroy,
fg_color='#2c2c2e' if self.dark_mode else '#e5e5e7',
hover_color='#3a3a3c' if self.dark_mode else '#d1d1d6',
text_color='white' if self.dark_mode else 'black'
)
back_btn.pack(side='left')
# Title
title = ctk.CTkLabel(
header_frame,
text=TRANSLATIONS[self.language]['wifi_diagnostics'],
font=("Helvetica", 22, "bold"),
text_color='white' if self.dark_mode else 'black'
)
title.pack(side='left', padx=20)
# Refresh button
self.refresh_btn = ctk.CTkButton(
header_frame,
text="⟳",
width=40,
command=self.scan_networks,
fg_color='#2c2c2e' if self.dark_mode else '#e5e5e7',
hover_color='#3a3a3c' if self.dark_mode else '#d1d1d6',
text_color='white' if self.dark_mode else 'black'
)
self.refresh_btn.pack(side='right')
def scan_networks(self):
if self.scanning:
return
self.scanning = True
self.refresh_btn.configure(state="disabled")
# Clear existing network list
for widget in self.scrollable_frame.winfo_children():
widget.destroy()
# Add scanning message
self.scanning_label = ctk.CTkLabel(
self.scrollable_frame,
text=TRANSLATIONS[self.language]['diagnostic_running'],
font=("Helvetica", 16),
text_color='white' if self.dark_mode else 'black'
)
self.scanning_label.pack(pady=20)
# Start scan in separate thread
thread = threading.Thread(target=self._scan_networks_thread)
thread.daemon = True
thread.start()
def _scan_networks_thread(self):
try:
# Get list of networks
result = subprocess.run(['sudo', 'iwlist', 'wlan0', 'scan'],
capture_output=True, text=True)
# Clear existing networks set
self.networks.clear()
# Parse networks from output and add to set (ensures uniqueness)
for line in result.stdout.split('\n'):
if "ESSID:" in line:
ssid = re.findall(r'ESSID:"([^"]*)"', line)
if ssid and ssid[0]:
self.networks.add(ssid[0])
# Update UI in main thread
self.after(0, self._update_network_list)
except Exception as e:
print(f"Error scanning networks: {e}")
self.after(0, self._show_scan_error)
finally:
self.scanning = False
self.after(0, lambda: self.refresh_btn.configure(state="normal"))
def _update_network_list(self):
# Remove scanning message
if hasattr(self, 'scanning_label'):
self.scanning_label.destroy()
# Get current network
current_network = self._get_current_network()
# Add network buttons
for network in sorted(self.networks):
network_frame = ctk.CTkFrame(
self.scrollable_frame,
fg_color='#2c2c2e' if self.dark_mode else '#e5e5e7',
corner_radius=10,
height=60
)
network_frame.pack(fill='x', pady=5, padx=10)
network_frame.pack_propagate(False)
# Network name
name_label = ctk.CTkLabel(
network_frame,
text=network,
font=("Helvetica", 16),
text_color='white' if self.dark_mode else 'black'
)
name_label.pack(side='left', padx=20, pady=10)
# Connection status/button
if network == current_network:
status_label = ctk.CTkLabel(
network_frame,
text=TRANSLATIONS[self.language]['wifi_connected'],
font=("Helvetica", 16),
text_color='#34c759'
)
status_label.pack(side='right', padx=20)
else:
connect_btn = ctk.CTkButton(
network_frame,
text=TRANSLATIONS[self.language]['reconnect'],
font=Editor is loading...
Leave a Comment