V1.2
@@ -0,0 +1,467 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import ttk
|
||||||
|
import configparser
|
||||||
|
from typing import Self
|
||||||
|
from threading import Thread
|
||||||
|
import threading
|
||||||
|
from datetime import datetime
|
||||||
|
import time
|
||||||
|
import socket
|
||||||
|
import os
|
||||||
|
from watchdog.observers import Observer
|
||||||
|
from watchdog.events import FileSystemEventHandler
|
||||||
|
import platform
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
|
||||||
|
class App(ttk.Frame):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.parent = parent
|
||||||
|
self.parent.title("Tally Triggers V1.2 HTTP")
|
||||||
|
|
||||||
|
|
||||||
|
# Create tabs
|
||||||
|
self.tabControl = ttk.Notebook(self.parent)
|
||||||
|
self.tab1 = ttk.Frame(self.tabControl)
|
||||||
|
self.tab2 = ttk.Frame(self.tabControl)
|
||||||
|
|
||||||
|
|
||||||
|
# Add tabs to the tab control
|
||||||
|
self.tabControl.add(self.tab1, text="Main")
|
||||||
|
self.tabControl.add(self.tab2, text="Settings")
|
||||||
|
self.tabControl.pack(expand=1, fill="both")
|
||||||
|
|
||||||
|
#Load Config
|
||||||
|
self.load_config()
|
||||||
|
|
||||||
|
# Start TCP1 listener thread
|
||||||
|
self.tcp_thread1 = threading.Thread(target=self.tcp_listener, args=(self.TCP_Port1,), daemon=True)
|
||||||
|
self.tcp_thread1.start()
|
||||||
|
|
||||||
|
# Start TCP2 listener thread
|
||||||
|
self.tcp_thread2 = threading.Thread(target=self.tcp_listener, args=(self.TCP_Port2,), daemon=True)
|
||||||
|
self.tcp_thread2.start()
|
||||||
|
|
||||||
|
|
||||||
|
# Create widgets
|
||||||
|
self.setup_widgets()
|
||||||
|
|
||||||
|
|
||||||
|
# Start Tally Box connectivity check thread
|
||||||
|
self.connection_thread = threading.Thread(target=self.check_tally_connection, daemon=True)
|
||||||
|
self.connection_thread.start()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def load_config(self):
|
||||||
|
# Load configuration
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read('Config.ini')
|
||||||
|
|
||||||
|
# Courts
|
||||||
|
self.Relay_1_Name = config['Courts']['Relay1']
|
||||||
|
self.Relay_2_Name = config['Courts']['Relay2']
|
||||||
|
|
||||||
|
|
||||||
|
#TMCC IPs
|
||||||
|
self.Relay1_TMCCIP = config['TMMC']['Relay1']
|
||||||
|
self.Relay2_TMCCIP = config['TMMC']['Relay2']
|
||||||
|
|
||||||
|
|
||||||
|
#TCP Commands
|
||||||
|
self.Relay1_Command = config['TCP Commands']['Relay1']
|
||||||
|
self.Relay2_Command = config['TCP Commands']['Relay2']
|
||||||
|
|
||||||
|
|
||||||
|
#General
|
||||||
|
self.TallyBoxIP = config['General']['TallyBoxIP']
|
||||||
|
self.TCP_Port1 = int(config['General']['TCP_Port1'])
|
||||||
|
self.TCP_Port2 = int(config['General']['TCP_Port2'])
|
||||||
|
self.On_Time = int(config['General']['On_Time'])
|
||||||
|
self.PosDistanceThreshold = int(config['General']['Pos_Dist'])
|
||||||
|
self.NegDistanceThreshold = int(config['General']['Neg_Dist'])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def setup_widgets(self):
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# Relay 1 Frame
|
||||||
|
self.Relay1_frame = ttk.LabelFrame(self.tab1, text="Relay 1", padding=(20, 10))
|
||||||
|
self.Relay1_frame.grid(
|
||||||
|
row=0, column=0, padx=(5, 5), pady=(20, 10), sticky="nsew"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Relay 1
|
||||||
|
self.Relay1 = ttk.Label(self.Relay1_frame,text=self.Relay_1_Name,justify="center",font=("-size", 10, "-weight", "bold"),
|
||||||
|
)
|
||||||
|
self.Relay1.grid(row=0, column=0, padx=0, pady=(0, 20), sticky="ns")
|
||||||
|
|
||||||
|
|
||||||
|
# Canvas for the circle
|
||||||
|
self.Relay1Status = tk.Canvas(self.Relay1_frame, width=45, height=50)
|
||||||
|
self.Relay1Status.grid(row=1, column=0, pady=(0, 10))
|
||||||
|
|
||||||
|
# Draw circle
|
||||||
|
self.oval_id1 = self.Relay1Status.create_oval(10, 10, 40, 40, fill="red", outline="grey")
|
||||||
|
|
||||||
|
# Relay 1 TMCC Connection
|
||||||
|
self.Relay1TMCCConnection = ttk.Label(self.Relay1_frame,text="TMCC",justify="center",font=("-size", 10, "-weight", "bold"),
|
||||||
|
)
|
||||||
|
self.Relay1TMCCConnection.grid(row=2, column=0, padx=0, pady=(0, 20), sticky="ns")
|
||||||
|
|
||||||
|
# Relay 1 last trigger time
|
||||||
|
self.Relay1time = ttk.Label(self.Relay1_frame,text="Never",justify="center",font=("-size", 10, "-weight", "bold"),
|
||||||
|
)
|
||||||
|
self.Relay1time.grid(row=3, column=0, padx=0, pady=(0, 20), sticky="ns")
|
||||||
|
|
||||||
|
# Test Button
|
||||||
|
self.Relay1button = ttk.Button(self.Relay1_frame, text="Test", style="Accent.TButton",width = 12, command=self.publish_relay1)
|
||||||
|
self.Relay1button.grid(row=4, column=0, padx=0, pady=10, sticky="nsew")
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# Relay 2 Frame
|
||||||
|
self.Relay2_frame = ttk.LabelFrame(self.tab1, text="Relay 2", padding=(20, 10))
|
||||||
|
self.Relay2_frame.grid(
|
||||||
|
row=0, column=1, padx=(5, 5), pady=(20, 10), sticky="nsew"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Entry Relay 2
|
||||||
|
self.Relay2 = ttk.Label(self.Relay2_frame,text=self.Relay_2_Name,justify="center",font=("-size", 10, "-weight", "bold"),
|
||||||
|
)
|
||||||
|
self.Relay2.grid(row=0, column=0, padx=0, pady=(0, 20), sticky="ns")
|
||||||
|
|
||||||
|
# Canvas for the circle
|
||||||
|
self.Relay2Status = tk.Canvas(self.Relay2_frame, width=45, height=50)
|
||||||
|
self.Relay2Status.grid(row=1, column=0, pady=(0, 10))
|
||||||
|
|
||||||
|
# Draw circle
|
||||||
|
self.oval_id2 = self.Relay2Status.create_oval(10, 10, 40, 40, fill="red", outline="grey")
|
||||||
|
|
||||||
|
# Relay 2 TMCC Connection
|
||||||
|
self.Relay2TMCCConnection = ttk.Label(self.Relay2_frame,text="TMCC",justify="center",font=("-size", 10, "-weight", "bold"),
|
||||||
|
)
|
||||||
|
self.Relay2TMCCConnection.grid(row=2, column=0, padx=0, pady=(0, 20), sticky="ns")
|
||||||
|
|
||||||
|
# Entry Relay 2 last trigger time
|
||||||
|
self.Relay2time = ttk.Label(self.Relay2_frame,text="Never",justify="center",font=("-size", 10, "-weight", "bold"),
|
||||||
|
)
|
||||||
|
self.Relay2time.grid(row=3, column=0, padx=0, pady=(0, 20), sticky="ns")
|
||||||
|
|
||||||
|
# Test Button
|
||||||
|
self.Relay2button = ttk.Button(self.Relay2_frame, text="Test", style="Accent.TButton",width = 12, command=self.publish_relay2)
|
||||||
|
self.Relay2button.grid(row=4, column=0, padx=0, pady=10, sticky="nsew")
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# Extras Frame
|
||||||
|
self.Extras_frame = ttk.LabelFrame(self.tab1, text="Extras", padding=(20, 10))
|
||||||
|
self.Extras_frame.grid(
|
||||||
|
row=1, column=0, columnspan = 8, padx=(5, 5), pady=(5, 5), sticky="nsew"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Connection Status
|
||||||
|
self.ConnectionStatus = ttk.Label(self.Extras_frame,text="Connected to Tally Box:",justify="center",font=("-size", 10, "-weight", "bold"),
|
||||||
|
)
|
||||||
|
self.ConnectionStatus.grid(row=0, column=0, padx=0, pady=(0, 0), sticky="ew")
|
||||||
|
|
||||||
|
# Canvas for the circle
|
||||||
|
self.ConnectionStatusLight = tk.Canvas(self.Extras_frame, width=50, height=50)
|
||||||
|
self.ConnectionStatusLight.grid(row=0, column=1, pady=(0, 0))
|
||||||
|
|
||||||
|
# Draw circle
|
||||||
|
self.oval_id9 = self.ConnectionStatusLight.create_oval(10, 10, 40, 40, fill="red", outline="grey")
|
||||||
|
|
||||||
|
# Test All Button
|
||||||
|
self.TestAllButton = ttk.Button(self.Extras_frame, text="Test All", style="Accent.TButton",width = 12, command=self.publish_relay_all)
|
||||||
|
self.TestAllButton.grid(row=0, column=4, padx=(50,0), pady=0, sticky="nsew")
|
||||||
|
|
||||||
|
|
||||||
|
#######################################################################################
|
||||||
|
#####################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Relay 1 Settings Frame
|
||||||
|
self.Relay1_frame = ttk.LabelFrame(self.tab2, text="Relay 1", padding=(20, 10))
|
||||||
|
self.Relay1_frame.grid(
|
||||||
|
row=0, column=0, padx=(5, 5), pady=(20, 10), sticky="nsew"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Label Relay 1 Courtname
|
||||||
|
self.Relay1Name = ttk.Label(self.Relay1_frame,text="Court Name",justify="center",font=("-size", 10, "-weight", "bold"),
|
||||||
|
)
|
||||||
|
self.Relay1Name.grid(row=0, column=0, padx=0, pady=(0, 20), sticky="ns")
|
||||||
|
|
||||||
|
# Entry Relay 1 Courtname
|
||||||
|
self.Relay1Entry = ttk.Entry(self.Relay1_frame, textvariable=self.Relay_1_Name, justify="center", font=("-size", 10, "-weight", "bold"))
|
||||||
|
self.Relay1Entry.insert(0, self.Relay_1_Name)
|
||||||
|
self.Relay1Entry.grid(row=1, column=0, padx=0, pady=(0, 20), sticky="ew")
|
||||||
|
|
||||||
|
# Save Button
|
||||||
|
self.Save1button = ttk.Button(self.Relay1_frame, text="Save", style="Accent.TButton",width = 12, command=self.save_relay_names)
|
||||||
|
self.Save1button.grid(row=2, column=0, padx=0, pady=10, sticky="nsew")
|
||||||
|
###########################################################################################################################################
|
||||||
|
# Relay 2 Settings Frame
|
||||||
|
self.Relay2_frame = ttk.LabelFrame(self.tab2, text="Relay 2", padding=(20, 10))
|
||||||
|
self.Relay2_frame.grid(
|
||||||
|
row=0, column=1, padx=(5, 5), pady=(20, 10), sticky="nsew"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Label Relay 2 Courtname
|
||||||
|
self.Relay2Name = ttk.Label(self.Relay2_frame,text="Court Name",justify="center",font=("-size", 10, "-weight", "bold"),
|
||||||
|
)
|
||||||
|
self.Relay2Name.grid(row=0, column=0, padx=0, pady=(0, 20), sticky="ns")
|
||||||
|
|
||||||
|
# Entry Relay 2 Courtname
|
||||||
|
self.Relay2Entry = ttk.Entry(self.Relay2_frame, textvariable=self.Relay_2_Name, justify="center", font=("-size", 10, "-weight", "bold"))
|
||||||
|
self.Relay2Entry.insert(0, self.Relay_2_Name)
|
||||||
|
self.Relay2Entry.grid(row=1, column=0, padx=0, pady=(0, 20), sticky="ew")
|
||||||
|
|
||||||
|
# Save Button
|
||||||
|
self.Save2button = ttk.Button(self.Relay2_frame, text="Save", style="Accent.TButton",width = 12, command=self.save_relay_names)
|
||||||
|
self.Save2button.grid(row=2, column=0, padx=0, pady=10, sticky="nsew")
|
||||||
|
###########################################################################################################################################
|
||||||
|
|
||||||
|
# Function to send a TCP message to the TALLY BOX
|
||||||
|
def send_message(self, command, timeout=5):
|
||||||
|
try:
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
s.settimeout(timeout)
|
||||||
|
s.connect((self.TallyBoxIP, 17494))
|
||||||
|
|
||||||
|
# command may already be bytes, so handle both cases
|
||||||
|
if isinstance(command, str):
|
||||||
|
s.sendall(bytes.fromhex(command))
|
||||||
|
else:
|
||||||
|
s.sendall(command)
|
||||||
|
|
||||||
|
data = s.recv(1024)
|
||||||
|
return data # Return response bytes
|
||||||
|
except (socket.timeout, ConnectionRefusedError, socket.error) as e:
|
||||||
|
print(f"Error sending message: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def publish_relay1(self):
|
||||||
|
def toggle_relay1():
|
||||||
|
relay_id = 1
|
||||||
|
|
||||||
|
# ---- Turn ON ----
|
||||||
|
message = bytes([0x20, relay_id, 0x00])
|
||||||
|
response = self.send_message(message)
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
||||||
|
print(f"[{current_time}] Sent command: 20 {relay_id:02X} 00 - Relay {relay_id} ON")
|
||||||
|
|
||||||
|
if response:
|
||||||
|
resp_val = response[0]
|
||||||
|
print(f"[{current_time}] Device response: {resp_val}")
|
||||||
|
if resp_val == 0:
|
||||||
|
self.Relay1Status.itemconfig(self.oval_id1, fill="green")
|
||||||
|
self.Relay1time.config(text=current_time)
|
||||||
|
else:
|
||||||
|
print(f"[{current_time}] Relay {relay_id} ON failed (response={resp_val})")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
print(f"[{current_time}] No response from device for Relay {relay_id} ON")
|
||||||
|
return
|
||||||
|
|
||||||
|
time.sleep(self.On_Time)
|
||||||
|
|
||||||
|
# ---- Turn OFF ----
|
||||||
|
message = bytes([0x21, relay_id, 0x00])
|
||||||
|
response = self.send_message(message)
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
||||||
|
print(f"[{current_time}] Sent command: 21 {relay_id:02X} 00 - Relay {relay_id} OFF")
|
||||||
|
|
||||||
|
if response:
|
||||||
|
resp_val = response[0]
|
||||||
|
print(f"[{current_time}] Device response: {resp_val}")
|
||||||
|
if resp_val == 0:
|
||||||
|
self.Relay1Status.itemconfig(self.oval_id2, fill="red")
|
||||||
|
else:
|
||||||
|
print(f"[{current_time}] Relay {relay_id} OFF failed (response={resp_val})")
|
||||||
|
else:
|
||||||
|
print(f"[{current_time}] No response from device for Relay {relay_id} OFF")
|
||||||
|
|
||||||
|
threading.Thread(target=toggle_relay1, daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
|
def publish_relay2(self):
|
||||||
|
def toggle_relay2():
|
||||||
|
relay_id = 2
|
||||||
|
|
||||||
|
# ---- Turn ON ----
|
||||||
|
message = bytes([0x20, relay_id, 0x00])
|
||||||
|
response = self.send_message(message)
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
||||||
|
print(f"[{current_time}] Sent command: 20 {relay_id:02X} 00 - Relay {relay_id} ON")
|
||||||
|
|
||||||
|
if response:
|
||||||
|
resp_val = response[0]
|
||||||
|
print(f"[{current_time}] Device response: {resp_val}")
|
||||||
|
if resp_val == 0:
|
||||||
|
self.Relay2Status.itemconfig(self.oval_id2, fill="green")
|
||||||
|
self.Relay2time.config(text=current_time)
|
||||||
|
else:
|
||||||
|
print(f"[{current_time}] Relay {relay_id} ON failed (response={resp_val})")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
print(f"[{current_time}] No response from device for Relay {relay_id} ON")
|
||||||
|
return
|
||||||
|
|
||||||
|
time.sleep(self.On_Time)
|
||||||
|
|
||||||
|
# ---- Turn OFF ----
|
||||||
|
message = bytes([0x21, relay_id, 0x00])
|
||||||
|
response = self.send_message(message)
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
||||||
|
print(f"[{current_time}] Sent command: 21 {relay_id:02X} 00 - Relay {relay_id} OFF")
|
||||||
|
|
||||||
|
if response:
|
||||||
|
resp_val = response[0]
|
||||||
|
print(f"[{current_time}] Device response: {resp_val}")
|
||||||
|
if resp_val == 0:
|
||||||
|
self.Relay2Status.itemconfig(self.oval_id2, fill="red")
|
||||||
|
else:
|
||||||
|
print(f"[{current_time}] Relay {relay_id} OFF failed (response={resp_val})")
|
||||||
|
else:
|
||||||
|
print(f"[{current_time}] No response from device for Relay {relay_id} OFF")
|
||||||
|
|
||||||
|
threading.Thread(target=toggle_relay2, daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def publish_relay_all(self):
|
||||||
|
self.publish_relay1()
|
||||||
|
self.publish_relay2()
|
||||||
|
|
||||||
|
def check_tally_connection(self):
|
||||||
|
"""Continuously checks if the Tally Box is reachable and updates the status light."""
|
||||||
|
while True:
|
||||||
|
if self.ping_tally_box():
|
||||||
|
self.ConnectionStatusLight.itemconfig(self.oval_id9, fill="green") # Change to green if reachable
|
||||||
|
else:
|
||||||
|
self.ConnectionStatusLight.itemconfig(self.oval_id9, fill="red") # Change to red if unreachable
|
||||||
|
time.sleep(5) # Check every 5 seconds
|
||||||
|
|
||||||
|
def ping_tally_box(self):
|
||||||
|
"""Pings the Tally Box IP to check connectivity."""
|
||||||
|
param = "-n" if platform.system().lower() == "windows" else "-c"
|
||||||
|
command = ["ping", param, "1", self.TallyBoxIP]
|
||||||
|
try:
|
||||||
|
subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
|
||||||
|
return True # Ping was successful
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return False # Ping failed
|
||||||
|
|
||||||
|
def save_relay_names(self):
|
||||||
|
"""Saves the Relay 1 and Relay 2 names to the Config.ini file and updates the UI labels."""
|
||||||
|
new_relay1_name = self.Relay1Entry.get()
|
||||||
|
new_relay2_name = self.Relay2Entry.get()
|
||||||
|
|
||||||
|
# Update labels in the UI
|
||||||
|
self.Relay1.config(text=new_relay1_name)
|
||||||
|
self.Relay2.config(text=new_relay2_name)
|
||||||
|
|
||||||
|
# Update the config file
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read('Config.ini')
|
||||||
|
|
||||||
|
if 'Courts' not in config:
|
||||||
|
config['Courts'] = {}
|
||||||
|
|
||||||
|
config['Courts']['Relay1'] = new_relay1_name
|
||||||
|
config['Courts']['Relay2'] = new_relay2_name
|
||||||
|
|
||||||
|
with open('Config.ini', 'w') as configfile:
|
||||||
|
config.write(configfile)
|
||||||
|
|
||||||
|
print("Config updated successfully!")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def tcp_listener(self, port):
|
||||||
|
# TCP/IP socket setup
|
||||||
|
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
server_socket.bind(('0.0.0.0', port)) # Bind to all interfaces
|
||||||
|
server_socket.listen(1) # Listen for incoming connections
|
||||||
|
|
||||||
|
print(f"TCP server listening on port {port} \n")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Accept a connection
|
||||||
|
conn, addr = server_socket.accept()
|
||||||
|
print(f"Connection from {addr} on port {port}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Receive the message
|
||||||
|
message = conn.recv(1024).decode('utf-8').strip()
|
||||||
|
print(f"Received raw message: {message}")
|
||||||
|
|
||||||
|
# Extract values using regular expressions
|
||||||
|
close_call_match = re.search(r'"Close Call":\s*"(\w+)"', message)
|
||||||
|
distance_match = re.search(r'"Distance":\s*(-?[\d\.]+)', message)
|
||||||
|
|
||||||
|
if not (close_call_match and distance_match):
|
||||||
|
print("Error: Invalid message format")
|
||||||
|
continue # Skip processing this message
|
||||||
|
|
||||||
|
# Convert extracted values
|
||||||
|
close_call = close_call_match.group(1) == "True"
|
||||||
|
distance = float(distance_match.group(1))
|
||||||
|
|
||||||
|
# Check if Close Call is True and within tolerance
|
||||||
|
if close_call:
|
||||||
|
if port == self.TCP_Port1:
|
||||||
|
self.publish_relay1()
|
||||||
|
elif port == self.TCP_Port2:
|
||||||
|
self.publish_relay2()
|
||||||
|
else:
|
||||||
|
print(f"Message received but conditions not met for port {port}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error processing message: {e}")
|
||||||
|
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
root = tk.Tk()
|
||||||
|
root.title("Tally Triggers V1.2 HTTP")
|
||||||
|
root.iconbitmap(r'Resources/icon1.ico')
|
||||||
|
|
||||||
|
|
||||||
|
# Simply set the theme
|
||||||
|
root.tk.call("source", "Resources/azure.tcl")
|
||||||
|
root.tk.call("set_theme", "dark")
|
||||||
|
|
||||||
|
app = App(root)
|
||||||
|
app.pack(fill="both", expand=True)
|
||||||
|
|
||||||
|
|
||||||
|
# Set a minsize for the window, and place it in the middle
|
||||||
|
root.update()
|
||||||
|
root.minsize(root.winfo_width(), root.winfo_height())
|
||||||
|
|
||||||
|
|
||||||
|
root.mainloop()
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
[Courts]
|
||||||
|
relay1 = Stadium 1
|
||||||
|
relay2 = Stadium 2
|
||||||
|
|
||||||
|
[TMMC]
|
||||||
|
relay1 = 10.10.0.51
|
||||||
|
relay2 = 10.10.1.51
|
||||||
|
|
||||||
|
[TCP Commands]
|
||||||
|
relay1 = run replay 1
|
||||||
|
relay2 = run replay 2
|
||||||
|
|
||||||
|
[General]
|
||||||
|
tallyboxip = 127.0.0.1
|
||||||
|
tcp_port1 = 42000
|
||||||
|
tcp_port2 = 42001
|
||||||
|
on_time = 5
|
||||||
|
pos_dist = 10
|
||||||
|
neg_dist = 10
|
||||||
|
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
# Copyright © 2021 rdbende <rdbende@gmail.com>
|
||||||
|
|
||||||
|
source [file join [file dirname [info script]] theme light.tcl]
|
||||||
|
source [file join [file dirname [info script]] theme dark.tcl]
|
||||||
|
|
||||||
|
option add *tearOff 0
|
||||||
|
|
||||||
|
proc set_theme {mode} {
|
||||||
|
if {$mode == "dark"} {
|
||||||
|
ttk::style theme use "azure-dark"
|
||||||
|
|
||||||
|
array set colors {
|
||||||
|
-fg "#ffffff"
|
||||||
|
-bg "#333333"
|
||||||
|
-disabledfg "#ffffff"
|
||||||
|
-disabledbg "#737373"
|
||||||
|
-selectfg "#ffffff"
|
||||||
|
-selectbg "#007fff"
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style configure . \
|
||||||
|
-background $colors(-bg) \
|
||||||
|
-foreground $colors(-fg) \
|
||||||
|
-troughcolor $colors(-bg) \
|
||||||
|
-focuscolor $colors(-selectbg) \
|
||||||
|
-selectbackground $colors(-selectbg) \
|
||||||
|
-selectforeground $colors(-selectfg) \
|
||||||
|
-insertcolor $colors(-fg) \
|
||||||
|
-insertwidth 1 \
|
||||||
|
-fieldbackground $colors(-selectbg) \
|
||||||
|
-font {"Segoe Ui" 10} \
|
||||||
|
-borderwidth 1 \
|
||||||
|
-relief flat
|
||||||
|
|
||||||
|
tk_setPalette background [ttk::style lookup . -background] \
|
||||||
|
foreground [ttk::style lookup . -foreground] \
|
||||||
|
highlightColor [ttk::style lookup . -focuscolor] \
|
||||||
|
selectBackground [ttk::style lookup . -selectbackground] \
|
||||||
|
selectForeground [ttk::style lookup . -selectforeground] \
|
||||||
|
activeBackground [ttk::style lookup . -selectbackground] \
|
||||||
|
activeForeground [ttk::style lookup . -selectforeground]
|
||||||
|
|
||||||
|
ttk::style map . -foreground [list disabled $colors(-disabledfg)]
|
||||||
|
|
||||||
|
option add *font [ttk::style lookup . -font]
|
||||||
|
option add *Menu.selectcolor $colors(-fg)
|
||||||
|
|
||||||
|
} elseif {$mode == "light"} {
|
||||||
|
ttk::style theme use "azure-light"
|
||||||
|
|
||||||
|
array set colors {
|
||||||
|
-fg "#000000"
|
||||||
|
-bg "#ffffff"
|
||||||
|
-disabledfg "#737373"
|
||||||
|
-disabledbg "#ffffff"
|
||||||
|
-selectfg "#ffffff"
|
||||||
|
-selectbg "#007fff"
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style configure . \
|
||||||
|
-background $colors(-bg) \
|
||||||
|
-foreground $colors(-fg) \
|
||||||
|
-troughcolor $colors(-bg) \
|
||||||
|
-focuscolor $colors(-selectbg) \
|
||||||
|
-selectbackground $colors(-selectbg) \
|
||||||
|
-selectforeground $colors(-selectfg) \
|
||||||
|
-insertcolor $colors(-fg) \
|
||||||
|
-insertwidth 1 \
|
||||||
|
-fieldbackground $colors(-selectbg) \
|
||||||
|
-font {"Segoe Ui" 10} \
|
||||||
|
-borderwidth 1 \
|
||||||
|
-relief flat
|
||||||
|
|
||||||
|
tk_setPalette background [ttk::style lookup . -background] \
|
||||||
|
foreground [ttk::style lookup . -foreground] \
|
||||||
|
highlightColor [ttk::style lookup . -focuscolor] \
|
||||||
|
selectBackground [ttk::style lookup . -selectbackground] \
|
||||||
|
selectForeground [ttk::style lookup . -selectforeground] \
|
||||||
|
activeBackground [ttk::style lookup . -selectbackground] \
|
||||||
|
activeForeground [ttk::style lookup . -selectforeground]
|
||||||
|
|
||||||
|
ttk::style map . -foreground [list disabled $colors(-disabledfg)]
|
||||||
|
|
||||||
|
option add *font [ttk::style lookup . -font]
|
||||||
|
option add *Menu.selectcolor $colors(-fg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,537 @@
|
|||||||
|
# Copyright (c) 2021 rdbende <rdbende@gmail.com>
|
||||||
|
|
||||||
|
# The Azure theme is a beautiful modern ttk theme inspired by Microsoft's fluent design.
|
||||||
|
|
||||||
|
package require Tk 8.6
|
||||||
|
|
||||||
|
namespace eval ttk::theme::azure-dark {
|
||||||
|
variable version 2.0
|
||||||
|
package provide ttk::theme::azure-dark $version
|
||||||
|
|
||||||
|
ttk::style theme create azure-dark -parent clam -settings {
|
||||||
|
proc load_images {imgdir} {
|
||||||
|
variable I
|
||||||
|
foreach file [glob -directory $imgdir *.png] {
|
||||||
|
set img [file tail [file rootname $file]]
|
||||||
|
set I($img) [image create photo -file $file -format png]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
load_images [file join [file dirname [info script]] dark]
|
||||||
|
|
||||||
|
array set colors {
|
||||||
|
-fg "#ffffff"
|
||||||
|
-bg "#333333"
|
||||||
|
-disabledfg "#ffffff"
|
||||||
|
-disabledbg "#737373"
|
||||||
|
-selectfg "#ffffff"
|
||||||
|
-selectbg "#007fff"
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TButton {
|
||||||
|
Button.button -children {
|
||||||
|
Button.padding -children {
|
||||||
|
Button.label -side left -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Toolbutton {
|
||||||
|
Toolbutton.button -children {
|
||||||
|
Toolbutton.padding -children {
|
||||||
|
Toolbutton.label -side left -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TMenubutton {
|
||||||
|
Menubutton.button -children {
|
||||||
|
Menubutton.padding -children {
|
||||||
|
Menubutton.indicator -side right
|
||||||
|
Menubutton.label -side right -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TOptionMenu {
|
||||||
|
OptionMenu.button -children {
|
||||||
|
OptionMenu.padding -children {
|
||||||
|
OptionMenu.indicator -side right
|
||||||
|
OptionMenu.label -side right -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Accent.TButton {
|
||||||
|
AccentButton.button -children {
|
||||||
|
AccentButton.padding -children {
|
||||||
|
AccentButton.label -side left -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TCheckbutton {
|
||||||
|
Checkbutton.button -children {
|
||||||
|
Checkbutton.padding -children {
|
||||||
|
Checkbutton.indicator -side left
|
||||||
|
Checkbutton.label -side right -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Switch.TCheckbutton {
|
||||||
|
Switch.button -children {
|
||||||
|
Switch.padding -children {
|
||||||
|
Switch.indicator -side left
|
||||||
|
Switch.label -side right -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Toggle.TButton {
|
||||||
|
ToggleButton.button -children {
|
||||||
|
ToggleButton.padding -children {
|
||||||
|
ToggleButton.label -side left -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TRadiobutton {
|
||||||
|
Radiobutton.button -children {
|
||||||
|
Radiobutton.padding -children {
|
||||||
|
Radiobutton.indicator -side left
|
||||||
|
Radiobutton.label -side right -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Vertical.TScrollbar {
|
||||||
|
Vertical.Scrollbar.trough -sticky ns -children {
|
||||||
|
Vertical.Scrollbar.thumb -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Horizontal.TScrollbar {
|
||||||
|
Horizontal.Scrollbar.trough -sticky ew -children {
|
||||||
|
Horizontal.Scrollbar.thumb -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TCombobox {
|
||||||
|
Combobox.field -sticky nswe -children {
|
||||||
|
Combobox.padding -expand true -sticky nswe -children {
|
||||||
|
Combobox.textarea -sticky nswe
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Combobox.button -side right -sticky ns -children {
|
||||||
|
Combobox.arrow -sticky nsew
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TSpinbox {
|
||||||
|
Spinbox.field -sticky nsew -children {
|
||||||
|
Spinbox.padding -expand true -sticky nswe -children {
|
||||||
|
Spinbox.textarea -sticky nswe
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Spinbox.button -side right -sticky ns -children {
|
||||||
|
null -side right -children {
|
||||||
|
Spinbox.uparrow -side top
|
||||||
|
Spinbox.downarrow -side bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Horizontal.TSeparator {
|
||||||
|
Horizontal.separator -sticky nswe
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Vertical.TSeparator {
|
||||||
|
Vertical.separator -sticky nswe
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Horizontal.Tick.TScale {
|
||||||
|
Horizontal.TickScale.trough -sticky ew -children {
|
||||||
|
Horizontal.TickScale.slider -sticky w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Vertical.Tick.TScale {
|
||||||
|
Vertical.TickScale.trough -sticky ns -children {
|
||||||
|
Vertical.TickScale.slider -sticky n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Card.TFrame {
|
||||||
|
Card.field {
|
||||||
|
Card.padding -expand 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TLabelframe {
|
||||||
|
Labelframe.border {
|
||||||
|
Labelframe.padding -expand 1 -children {
|
||||||
|
Labelframe.label -side right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TNotebook.Tab {
|
||||||
|
Notebook.tab -children {
|
||||||
|
Notebook.padding -side top -children {
|
||||||
|
Notebook.label -side top -sticky {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Treeview.Item {
|
||||||
|
Treeitem.padding -sticky nswe -children {
|
||||||
|
Treeitem.indicator -side left -sticky {}
|
||||||
|
Treeitem.image -side left -sticky {}
|
||||||
|
Treeitem.text -side left -sticky {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Elements
|
||||||
|
|
||||||
|
# Button
|
||||||
|
ttk::style configure TButton -padding {8 4 8 4} -width -10 -anchor center
|
||||||
|
|
||||||
|
ttk::style element create Button.button image \
|
||||||
|
[list $I(rect-basic) \
|
||||||
|
{selected disabled} $I(rect-basic) \
|
||||||
|
disabled $I(rect-basic) \
|
||||||
|
pressed $I(rect-basic) \
|
||||||
|
selected $I(rect-basic) \
|
||||||
|
active $I(button-hover) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
# Toolbutton
|
||||||
|
ttk::style configure Toolbutton -padding {8 4 8 4} -width -10 -anchor center
|
||||||
|
|
||||||
|
ttk::style element create Toolbutton.button image \
|
||||||
|
[list $I(empty) \
|
||||||
|
{selected disabled} $I(empty) \
|
||||||
|
disabled $I(empty) \
|
||||||
|
pressed $I(rect-basic) \
|
||||||
|
selected $I(rect-basic) \
|
||||||
|
active $I(rect-basic) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
# Menubutton
|
||||||
|
ttk::style configure TMenubutton -padding {8 4 4 4}
|
||||||
|
|
||||||
|
ttk::style element create Menubutton.button \
|
||||||
|
image [list $I(rect-basic) \
|
||||||
|
disabled $I(rect-basic) \
|
||||||
|
pressed $I(rect-basic) \
|
||||||
|
active $I(button-hover) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
ttk::style element create Menubutton.indicator \
|
||||||
|
image [list $I(down) \
|
||||||
|
active $I(down) \
|
||||||
|
pressed $I(down) \
|
||||||
|
disabled $I(down) \
|
||||||
|
] -width 15 -sticky e
|
||||||
|
|
||||||
|
# OptionMenu
|
||||||
|
ttk::style configure TOptionMenu -padding {8 4 4 4}
|
||||||
|
|
||||||
|
ttk::style element create OptionMenu.button \
|
||||||
|
image [list $I(rect-basic) \
|
||||||
|
disabled $I(rect-basic) \
|
||||||
|
pressed $I(rect-basic) \
|
||||||
|
active $I(button-hover) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
ttk::style element create OptionMenu.indicator \
|
||||||
|
image [list $I(down) \
|
||||||
|
active $I(down) \
|
||||||
|
pressed $I(down) \
|
||||||
|
disabled $I(down) \
|
||||||
|
] -width 15 -sticky e
|
||||||
|
|
||||||
|
# AccentButton
|
||||||
|
ttk::style configure Accent.TButton -padding {8 4 8 4} -width -10 -anchor center
|
||||||
|
|
||||||
|
ttk::style element create AccentButton.button image \
|
||||||
|
[list $I(rect-accent) \
|
||||||
|
{selected disabled} $I(rect-accent-hover) \
|
||||||
|
disabled $I(rect-accent-hover) \
|
||||||
|
pressed $I(rect-accent) \
|
||||||
|
selected $I(rect-accent) \
|
||||||
|
active $I(rect-accent-hover) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
# Checkbutton
|
||||||
|
ttk::style configure TCheckbutton -padding 4
|
||||||
|
|
||||||
|
ttk::style element create Checkbutton.indicator image \
|
||||||
|
[list $I(box-basic) \
|
||||||
|
{alternate disabled} $I(check-tri-basic) \
|
||||||
|
{selected disabled} $I(check-basic) \
|
||||||
|
disabled $I(box-basic) \
|
||||||
|
{pressed alternate} $I(check-tri-hover) \
|
||||||
|
{active alternate} $I(check-tri-hover) \
|
||||||
|
alternate $I(check-tri-accent) \
|
||||||
|
{pressed selected} $I(check-hover) \
|
||||||
|
{active selected} $I(check-hover) \
|
||||||
|
selected $I(check-accent) \
|
||||||
|
{pressed !selected} $I(rect-hover) \
|
||||||
|
active $I(box-hover) \
|
||||||
|
] -width 26 -sticky w
|
||||||
|
|
||||||
|
# Switch
|
||||||
|
ttk::style element create Switch.indicator image \
|
||||||
|
[list $I(off-basic) \
|
||||||
|
{selected disabled} $I(on-basic) \
|
||||||
|
disabled $I(off-basic) \
|
||||||
|
{pressed selected} $I(on-accent) \
|
||||||
|
{active selected} $I(on-accent) \
|
||||||
|
selected $I(on-accent) \
|
||||||
|
{pressed !selected} $I(off-basic) \
|
||||||
|
active $I(off-basic) \
|
||||||
|
] -width 46 -sticky w
|
||||||
|
|
||||||
|
# ToggleButton
|
||||||
|
ttk::style configure Toggle.TButton -padding {8 4 8 4} -width -10 -anchor center
|
||||||
|
|
||||||
|
ttk::style element create ToggleButton.button image \
|
||||||
|
[list $I(rect-basic) \
|
||||||
|
{selected disabled} $I(rect-accent-hover) \
|
||||||
|
disabled $I(rect-basic) \
|
||||||
|
{pressed selected} $I(rect-basic) \
|
||||||
|
{active selected} $I(rect-accent) \
|
||||||
|
selected $I(rect-accent) \
|
||||||
|
{pressed !selected} $I(rect-accent) \
|
||||||
|
active $I(rect-basic) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
# Radiobutton
|
||||||
|
ttk::style configure TRadiobutton -padding 4
|
||||||
|
|
||||||
|
ttk::style element create Radiobutton.indicator image \
|
||||||
|
[list $I(outline-basic) \
|
||||||
|
{alternate disabled} $I(radio-tri-basic) \
|
||||||
|
{selected disabled} $I(radio-basic) \
|
||||||
|
disabled $I(outline-basic) \
|
||||||
|
{pressed alternate} $I(radio-tri-hover) \
|
||||||
|
{active alternate} $I(radio-tri-hover) \
|
||||||
|
alternate $I(radio-tri-accent) \
|
||||||
|
{pressed selected} $I(radio-hover) \
|
||||||
|
{active selected} $I(radio-hover) \
|
||||||
|
selected $I(radio-accent) \
|
||||||
|
{pressed !selected} $I(circle-hover) \
|
||||||
|
active $I(outline-hover) \
|
||||||
|
] -width 26 -sticky w
|
||||||
|
|
||||||
|
# Scrollbar
|
||||||
|
ttk::style element create Horizontal.Scrollbar.trough image $I(hor-basic) \
|
||||||
|
-sticky ew
|
||||||
|
|
||||||
|
ttk::style element create Horizontal.Scrollbar.thumb \
|
||||||
|
image [list $I(hor-accent) \
|
||||||
|
disabled $I(hor-basic) \
|
||||||
|
pressed $I(hor-hover) \
|
||||||
|
active $I(hor-hover) \
|
||||||
|
] -sticky ew
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Scrollbar.trough image $I(vert-basic) \
|
||||||
|
-sticky ns
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Scrollbar.thumb \
|
||||||
|
image [list $I(vert-accent) \
|
||||||
|
disabled $I(vert-basic) \
|
||||||
|
pressed $I(vert-hover) \
|
||||||
|
active $I(vert-hover) \
|
||||||
|
] -sticky ns
|
||||||
|
|
||||||
|
# Scale
|
||||||
|
ttk::style element create Horizontal.Scale.trough image $I(scale-hor) \
|
||||||
|
-border 5 -padding 0
|
||||||
|
|
||||||
|
ttk::style element create Horizontal.Scale.slider \
|
||||||
|
image [list $I(circle-accent) \
|
||||||
|
disabled $I(circle-basic) \
|
||||||
|
pressed $I(circle-hover) \
|
||||||
|
active $I(circle-hover) \
|
||||||
|
] -sticky {}
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Scale.trough image $I(scale-vert) \
|
||||||
|
-border 5 -padding 0
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Scale.slider \
|
||||||
|
image [list $I(circle-accent) \
|
||||||
|
disabled $I(circle-basic) \
|
||||||
|
pressed $I(circle-hover) \
|
||||||
|
active $I(circle-hover) \
|
||||||
|
] -sticky {}
|
||||||
|
|
||||||
|
# Tickscale
|
||||||
|
ttk::style element create Horizontal.TickScale.trough image $I(scale-hor) \
|
||||||
|
-border 5 -padding 0
|
||||||
|
|
||||||
|
ttk::style element create Horizontal.TickScale.slider \
|
||||||
|
image [list $I(tick-hor-accent) \
|
||||||
|
disabled $I(tick-hor-basic) \
|
||||||
|
pressed $I(tick-hor-hover) \
|
||||||
|
active $I(tick-hor-hover) \
|
||||||
|
] -sticky {}
|
||||||
|
|
||||||
|
ttk::style element create Vertical.TickScale.trough image $I(scale-vert) \
|
||||||
|
-border 5 -padding 0
|
||||||
|
|
||||||
|
ttk::style element create Vertical.TickScale.slider \
|
||||||
|
image [list $I(tick-vert-accent) \
|
||||||
|
disabled $I(tick-vert-basic) \
|
||||||
|
pressed $I(tick-vert-hover) \
|
||||||
|
active $I(tick-vert-hover) \
|
||||||
|
] -sticky {}
|
||||||
|
|
||||||
|
# Progressbar
|
||||||
|
ttk::style element create Horizontal.Progressbar.trough image $I(hor-basic) \
|
||||||
|
-sticky ew
|
||||||
|
|
||||||
|
ttk::style element create Horizontal.Progressbar.pbar image $I(hor-accent) \
|
||||||
|
-sticky ew
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Progressbar.trough image $I(vert-basic) \
|
||||||
|
-sticky ns
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Progressbar.pbar image $I(vert-accent) \
|
||||||
|
-sticky ns
|
||||||
|
|
||||||
|
# Entry
|
||||||
|
ttk::style element create Entry.field \
|
||||||
|
image [list $I(box-basic) \
|
||||||
|
{focus hover} $I(box-accent) \
|
||||||
|
invalid $I(box-invalid) \
|
||||||
|
disabled $I(box-basic) \
|
||||||
|
focus $I(box-accent) \
|
||||||
|
hover $I(box-hover) \
|
||||||
|
] -border 5 -padding {8} -sticky news
|
||||||
|
|
||||||
|
# Combobox
|
||||||
|
ttk::style map TCombobox -selectbackground [list \
|
||||||
|
{!focus} $colors(-selectbg) \
|
||||||
|
{readonly hover} $colors(-selectbg) \
|
||||||
|
{readonly focus} $colors(-selectbg) \
|
||||||
|
]
|
||||||
|
|
||||||
|
ttk::style map TCombobox -selectforeground [list \
|
||||||
|
{!focus} $colors(-selectfg) \
|
||||||
|
{readonly hover} $colors(-selectfg) \
|
||||||
|
{readonly focus} $colors(-selectfg) \
|
||||||
|
]
|
||||||
|
|
||||||
|
ttk::style element create Combobox.field \
|
||||||
|
image [list $I(box-basic) \
|
||||||
|
{readonly disabled} $I(rect-basic) \
|
||||||
|
{readonly pressed} $I(rect-basic) \
|
||||||
|
{readonly focus hover} $I(button-hover) \
|
||||||
|
{readonly focus} $I(button-hover) \
|
||||||
|
{readonly hover} $I(button-hover) \
|
||||||
|
{focus hover} $I(box-accent) \
|
||||||
|
readonly $I(rect-basic) \
|
||||||
|
invalid $I(box-invalid) \
|
||||||
|
disabled $I(box-basic) \
|
||||||
|
focus $I(box-accent) \
|
||||||
|
hover $I(box-hover) \
|
||||||
|
] -border 5 -padding {8}
|
||||||
|
|
||||||
|
ttk::style element create Combobox.button \
|
||||||
|
image [list $I(combo-button-basic) \
|
||||||
|
{!readonly focus} $I(combo-button-focus) \
|
||||||
|
{readonly focus} $I(combo-button-hover) \
|
||||||
|
{readonly hover} $I(combo-button-hover)
|
||||||
|
] -border 5 -padding {2 6 6 6}
|
||||||
|
|
||||||
|
ttk::style element create Combobox.arrow image $I(down) \
|
||||||
|
-width 15 -sticky e
|
||||||
|
|
||||||
|
# Spinbox
|
||||||
|
ttk::style element create Spinbox.field \
|
||||||
|
image [list $I(box-basic) \
|
||||||
|
invalid $I(box-invalid) \
|
||||||
|
disabled $I(box-basic) \
|
||||||
|
focus $I(box-accent) \
|
||||||
|
hover $I(box-hover) \
|
||||||
|
] -border 5 -padding {8} -sticky news
|
||||||
|
|
||||||
|
ttk::style element create Spinbox.uparrow \
|
||||||
|
image [list $I(up) \
|
||||||
|
disabled $I(up) \
|
||||||
|
pressed $I(up-accent) \
|
||||||
|
active $I(up-accent) \
|
||||||
|
] -border 4 -width 15 -sticky e
|
||||||
|
|
||||||
|
ttk::style element create Spinbox.downarrow \
|
||||||
|
image [list $I(down) \
|
||||||
|
disabled $I(down) \
|
||||||
|
pressed $I(down-accent) \
|
||||||
|
active $I(down-accent) \
|
||||||
|
] -border 4 -width 15 -sticky e
|
||||||
|
|
||||||
|
ttk::style element create Spinbox.button \
|
||||||
|
image [list $I(combo-button-basic) \
|
||||||
|
{!readonly focus} $I(combo-button-focus) \
|
||||||
|
{readonly focus} $I(combo-button-hover) \
|
||||||
|
{readonly hover} $I(combo-button-hover)
|
||||||
|
] -border 5 -padding {2 6 6 6}
|
||||||
|
|
||||||
|
# Sizegrip
|
||||||
|
ttk::style element create Sizegrip.sizegrip image $I(size) \
|
||||||
|
-sticky ewns
|
||||||
|
|
||||||
|
# Separator
|
||||||
|
ttk::style element create Horizontal.separator image $I(separator)
|
||||||
|
|
||||||
|
ttk::style element create Vertical.separator image $I(separator)
|
||||||
|
|
||||||
|
# Card
|
||||||
|
ttk::style element create Card.field image $I(card) \
|
||||||
|
-border 10 -padding 4 -sticky news
|
||||||
|
|
||||||
|
# Labelframe
|
||||||
|
ttk::style element create Labelframe.border image $I(card) \
|
||||||
|
-border 5 -padding 4 -sticky news
|
||||||
|
|
||||||
|
# Notebook
|
||||||
|
ttk::style element create Notebook.client \
|
||||||
|
image $I(notebook) -border 5
|
||||||
|
|
||||||
|
ttk::style element create Notebook.tab \
|
||||||
|
image [list $I(tab-disabled) \
|
||||||
|
selected $I(tab-basic) \
|
||||||
|
active $I(tab-hover) \
|
||||||
|
] -border 5 -padding {14 4}
|
||||||
|
|
||||||
|
# Treeview
|
||||||
|
ttk::style element create Treeview.field image $I(card) \
|
||||||
|
-border 5
|
||||||
|
|
||||||
|
ttk::style element create Treeheading.cell \
|
||||||
|
image [list $I(tree-basic) \
|
||||||
|
pressed $I(tree-pressed)
|
||||||
|
] -border 5 -padding 4 -sticky ewns
|
||||||
|
|
||||||
|
ttk::style element create Treeitem.indicator \
|
||||||
|
image [list $I(right) \
|
||||||
|
user2 $I(empty) \
|
||||||
|
user1 $I(down) \
|
||||||
|
] -width 26 -sticky {}
|
||||||
|
|
||||||
|
ttk::style configure Treeview -background $colors(-bg)
|
||||||
|
ttk::style configure Treeview.Item -padding {2 0 0 0}
|
||||||
|
ttk::style map Treeview \
|
||||||
|
-background [list selected $colors(-selectbg)] \
|
||||||
|
-foreground [list selected $colors(-selectfg)]
|
||||||
|
|
||||||
|
# Panedwindow
|
||||||
|
# Insane hack to remove clam's ugly sash
|
||||||
|
ttk::style configure Sash -gripcount 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 424 B |
|
After Width: | Height: | Size: 330 B |
|
After Width: | Height: | Size: 357 B |
|
After Width: | Height: | Size: 405 B |
|
After Width: | Height: | Size: 346 B |
|
After Width: | Height: | Size: 457 B |
|
After Width: | Height: | Size: 482 B |
|
After Width: | Height: | Size: 423 B |
|
After Width: | Height: | Size: 453 B |
|
After Width: | Height: | Size: 346 B |
|
After Width: | Height: | Size: 310 B |
|
After Width: | Height: | Size: 326 B |
|
After Width: | Height: | Size: 484 B |
|
After Width: | Height: | Size: 437 B |
|
After Width: | Height: | Size: 470 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 297 B |
|
After Width: | Height: | Size: 234 B |
|
After Width: | Height: | Size: 261 B |
|
After Width: | Height: | Size: 130 B |
|
After Width: | Height: | Size: 154 B |
|
After Width: | Height: | Size: 156 B |
|
After Width: | Height: | Size: 154 B |
|
After Width: | Height: | Size: 410 B |
|
After Width: | Height: | Size: 677 B |
|
After Width: | Height: | Size: 736 B |
|
After Width: | Height: | Size: 668 B |
|
After Width: | Height: | Size: 587 B |
|
After Width: | Height: | Size: 644 B |
|
After Width: | Height: | Size: 629 B |
|
After Width: | Height: | Size: 561 B |
|
After Width: | Height: | Size: 625 B |
|
After Width: | Height: | Size: 524 B |
|
After Width: | Height: | Size: 505 B |
|
After Width: | Height: | Size: 466 B |
|
After Width: | Height: | Size: 289 B |
|
After Width: | Height: | Size: 319 B |
|
After Width: | Height: | Size: 286 B |
|
After Width: | Height: | Size: 297 B |
|
After Width: | Height: | Size: 255 B |
|
After Width: | Height: | Size: 161 B |
|
After Width: | Height: | Size: 161 B |
|
After Width: | Height: | Size: 128 B |
|
After Width: | Height: | Size: 477 B |
|
After Width: | Height: | Size: 249 B |
|
After Width: | Height: | Size: 234 B |
|
After Width: | Height: | Size: 260 B |
|
After Width: | Height: | Size: 302 B |
|
After Width: | Height: | Size: 267 B |
|
After Width: | Height: | Size: 280 B |
|
After Width: | Height: | Size: 295 B |
|
After Width: | Height: | Size: 257 B |
|
After Width: | Height: | Size: 277 B |
|
After Width: | Height: | Size: 149 B |
|
After Width: | Height: | Size: 168 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 271 B |
|
After Width: | Height: | Size: 158 B |
|
After Width: | Height: | Size: 158 B |
|
After Width: | Height: | Size: 158 B |
@@ -0,0 +1,537 @@
|
|||||||
|
# Copyright (c) 2021 rdbende <rdbende@gmail.com>
|
||||||
|
|
||||||
|
# The Azure theme is a beautiful modern ttk theme inspired by Microsoft's fluent design.
|
||||||
|
|
||||||
|
package require Tk 8.6
|
||||||
|
|
||||||
|
namespace eval ttk::theme::azure-light {
|
||||||
|
variable version 2.0
|
||||||
|
package provide ttk::theme::azure-light $version
|
||||||
|
|
||||||
|
ttk::style theme create azure-light -parent clam -settings {
|
||||||
|
proc load_images {imgdir} {
|
||||||
|
variable I
|
||||||
|
foreach file [glob -directory $imgdir *.png] {
|
||||||
|
set img [file tail [file rootname $file]]
|
||||||
|
set I($img) [image create photo -file $file -format png]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
load_images [file join [file dirname [info script]] light]
|
||||||
|
|
||||||
|
array set colors {
|
||||||
|
-fg "#000000"
|
||||||
|
-bg "#ffffff"
|
||||||
|
-disabledfg "#737373"
|
||||||
|
-disabledbg "#ffffff"
|
||||||
|
-selectfg "#ffffff"
|
||||||
|
-selectbg "#007fff"
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TButton {
|
||||||
|
Button.button -children {
|
||||||
|
Button.padding -children {
|
||||||
|
Button.label -side left -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Toolbutton {
|
||||||
|
Toolbutton.button -children {
|
||||||
|
Toolbutton.padding -children {
|
||||||
|
Toolbutton.label -side left -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TMenubutton {
|
||||||
|
Menubutton.button -children {
|
||||||
|
Menubutton.padding -children {
|
||||||
|
Menubutton.indicator -side right
|
||||||
|
Menubutton.label -side right -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TOptionMenu {
|
||||||
|
OptionMenu.button -children {
|
||||||
|
OptionMenu.padding -children {
|
||||||
|
OptionMenu.indicator -side right
|
||||||
|
OptionMenu.label -side right -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Accent.TButton {
|
||||||
|
AccentButton.button -children {
|
||||||
|
AccentButton.padding -children {
|
||||||
|
AccentButton.label -side left -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TCheckbutton {
|
||||||
|
Checkbutton.button -children {
|
||||||
|
Checkbutton.padding -children {
|
||||||
|
Checkbutton.indicator -side left
|
||||||
|
Checkbutton.label -side right -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Switch.TCheckbutton {
|
||||||
|
Switch.button -children {
|
||||||
|
Switch.padding -children {
|
||||||
|
Switch.indicator -side left
|
||||||
|
Switch.label -side right -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Toggle.TButton {
|
||||||
|
ToggleButton.button -children {
|
||||||
|
ToggleButton.padding -children {
|
||||||
|
ToggleButton.label -side left -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TRadiobutton {
|
||||||
|
Radiobutton.button -children {
|
||||||
|
Radiobutton.padding -children {
|
||||||
|
Radiobutton.indicator -side left
|
||||||
|
Radiobutton.label -side right -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Vertical.TScrollbar {
|
||||||
|
Vertical.Scrollbar.trough -sticky ns -children {
|
||||||
|
Vertical.Scrollbar.thumb -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Horizontal.TScrollbar {
|
||||||
|
Horizontal.Scrollbar.trough -sticky ew -children {
|
||||||
|
Horizontal.Scrollbar.thumb -expand true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TCombobox {
|
||||||
|
Combobox.field -sticky nswe -children {
|
||||||
|
Combobox.padding -expand true -sticky nswe -children {
|
||||||
|
Combobox.textarea -sticky nswe
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Combobox.button -side right -sticky ns -children {
|
||||||
|
Combobox.arrow -sticky nsew
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TSpinbox {
|
||||||
|
Spinbox.field -sticky nsew -children {
|
||||||
|
Spinbox.padding -expand true -sticky nswe -children {
|
||||||
|
Spinbox.textarea -sticky nswe
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Spinbox.button -side right -sticky ns -children {
|
||||||
|
null -side right -children {
|
||||||
|
Spinbox.uparrow -side top
|
||||||
|
Spinbox.downarrow -side bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Horizontal.TSeparator {
|
||||||
|
Horizontal.separator -sticky nswe
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Vertical.TSeparator {
|
||||||
|
Vertical.separator -sticky nswe
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Horizontal.Tick.TScale {
|
||||||
|
Horizontal.TickScale.trough -sticky ew -children {
|
||||||
|
Horizontal.TickScale.slider -sticky w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Vertical.Tick.TScale {
|
||||||
|
Vertical.TickScale.trough -sticky ns -children {
|
||||||
|
Vertical.TickScale.slider -sticky n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Card.TFrame {
|
||||||
|
Card.field {
|
||||||
|
Card.padding -expand 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TLabelframe {
|
||||||
|
Labelframe.border {
|
||||||
|
Labelframe.padding -expand 1 -children {
|
||||||
|
Labelframe.label -side right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout TNotebook.Tab {
|
||||||
|
Notebook.tab -children {
|
||||||
|
Notebook.padding -side top -children {
|
||||||
|
Notebook.label -side top -sticky {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttk::style layout Treeview.Item {
|
||||||
|
Treeitem.padding -sticky nswe -children {
|
||||||
|
Treeitem.indicator -side left -sticky {}
|
||||||
|
Treeitem.image -side left -sticky {}
|
||||||
|
Treeitem.text -side left -sticky {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Elements
|
||||||
|
|
||||||
|
# Button
|
||||||
|
ttk::style configure TButton -padding {8 4 8 4} -width -10 -anchor center
|
||||||
|
|
||||||
|
ttk::style element create Button.button image \
|
||||||
|
[list $I(rect-basic) \
|
||||||
|
{selected disabled} $I(rect-basic) \
|
||||||
|
disabled $I(rect-basic) \
|
||||||
|
selected $I(rect-basic) \
|
||||||
|
pressed $I(rect-basic) \
|
||||||
|
active $I(button-hover) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
# Toolbutton
|
||||||
|
ttk::style configure Toolbutton -padding {8 4 8 4} -width -10 -anchor center
|
||||||
|
|
||||||
|
ttk::style element create Toolbutton.button image \
|
||||||
|
[list $I(empty) \
|
||||||
|
{selected disabled} $I(empty) \
|
||||||
|
disabled $I(empty) \
|
||||||
|
selected $I(rect-basic) \
|
||||||
|
pressed $I(rect-basic) \
|
||||||
|
active $I(rect-basic) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
# Menubutton
|
||||||
|
ttk::style configure TMenubutton -padding {8 4 4 4}
|
||||||
|
|
||||||
|
ttk::style element create Menubutton.button \
|
||||||
|
image [list $I(rect-basic) \
|
||||||
|
disabled $I(rect-basic) \
|
||||||
|
pressed $I(rect-basic) \
|
||||||
|
active $I(button-hover) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
ttk::style element create Menubutton.indicator \
|
||||||
|
image [list $I(down) \
|
||||||
|
active $I(down) \
|
||||||
|
pressed $I(down) \
|
||||||
|
disabled $I(down) \
|
||||||
|
] -width 15 -sticky e
|
||||||
|
|
||||||
|
# OptionMenu
|
||||||
|
ttk::style configure TOptionMenu -padding {8 4 4 4}
|
||||||
|
|
||||||
|
ttk::style element create OptionMenu.button \
|
||||||
|
image [list $I(rect-basic) \
|
||||||
|
disabled $I(rect-basic) \
|
||||||
|
pressed $I(rect-basic) \
|
||||||
|
active $I(button-hover) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
ttk::style element create OptionMenu.indicator \
|
||||||
|
image [list $I(down) \
|
||||||
|
active $I(down) \
|
||||||
|
pressed $I(down) \
|
||||||
|
disabled $I(down) \
|
||||||
|
] -width 15 -sticky e
|
||||||
|
|
||||||
|
# AccentButton
|
||||||
|
ttk::style configure Accent.TButton -padding {8 4 8 4} -width -10 -anchor center
|
||||||
|
|
||||||
|
ttk::style element create AccentButton.button image \
|
||||||
|
[list $I(rect-accent) \
|
||||||
|
{selected disabled} $I(rect-accent-hover) \
|
||||||
|
disabled $I(rect-accent-hover) \
|
||||||
|
selected $I(rect-accent) \
|
||||||
|
pressed $I(rect-accent) \
|
||||||
|
active $I(rect-accent-hover) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
# Checkbutton
|
||||||
|
ttk::style configure TCheckbutton -padding 4
|
||||||
|
|
||||||
|
ttk::style element create Checkbutton.indicator image \
|
||||||
|
[list $I(box-basic) \
|
||||||
|
{alternate disabled} $I(check-tri-basic) \
|
||||||
|
{selected disabled} $I(check-basic) \
|
||||||
|
disabled $I(box-basic) \
|
||||||
|
{pressed alternate} $I(check-tri-hover) \
|
||||||
|
{active alternate} $I(check-tri-hover) \
|
||||||
|
alternate $I(check-tri-accent) \
|
||||||
|
{pressed selected} $I(check-hover) \
|
||||||
|
{active selected} $I(check-hover) \
|
||||||
|
selected $I(check-accent) \
|
||||||
|
{pressed !selected} $I(rect-hover) \
|
||||||
|
active $I(box-hover) \
|
||||||
|
] -width 26 -sticky w
|
||||||
|
|
||||||
|
# Switch
|
||||||
|
ttk::style element create Switch.indicator image \
|
||||||
|
[list $I(off-basic) \
|
||||||
|
{selected disabled} $I(on-basic) \
|
||||||
|
disabled $I(off-basic) \
|
||||||
|
{pressed selected} $I(on-hover) \
|
||||||
|
{active selected} $I(on-hover) \
|
||||||
|
selected $I(on-accent) \
|
||||||
|
{pressed !selected} $I(off-hover) \
|
||||||
|
active $I(off-hover) \
|
||||||
|
] -width 46 -sticky w
|
||||||
|
|
||||||
|
# ToggleButton
|
||||||
|
ttk::style configure Toggle.TButton -padding {8 4 8 4} -width -10 -anchor center
|
||||||
|
|
||||||
|
ttk::style element create ToggleButton.button image \
|
||||||
|
[list $I(rect-basic) \
|
||||||
|
{selected disabled} $I(rect-accent-hover) \
|
||||||
|
disabled $I(rect-basic) \
|
||||||
|
{pressed selected} $I(rect-basic) \
|
||||||
|
{active selected} $I(rect-accent) \
|
||||||
|
selected $I(rect-accent) \
|
||||||
|
{pressed !selected} $I(rect-accent) \
|
||||||
|
active $I(rect-basic) \
|
||||||
|
] -border 4 -sticky ewns
|
||||||
|
|
||||||
|
# Radiobutton
|
||||||
|
ttk::style configure TRadiobutton -padding 4
|
||||||
|
|
||||||
|
ttk::style element create Radiobutton.indicator image \
|
||||||
|
[list $I(outline-basic) \
|
||||||
|
{alternate disabled} $I(radio-tri-basic) \
|
||||||
|
{selected disabled} $I(radio-basic) \
|
||||||
|
disabled $I(outline-basic) \
|
||||||
|
{pressed alternate} $I(radio-tri-hover) \
|
||||||
|
{active alternate} $I(radio-tri-hover) \
|
||||||
|
alternate $I(radio-tri-accent) \
|
||||||
|
{pressed selected} $I(radio-hover) \
|
||||||
|
{active selected} $I(radio-hover) \
|
||||||
|
selected $I(radio-accent) \
|
||||||
|
{pressed !selected} $I(circle-hover) \
|
||||||
|
active $I(outline-hover) \
|
||||||
|
] -width 26 -sticky w
|
||||||
|
|
||||||
|
# Scrollbar
|
||||||
|
ttk::style element create Horizontal.Scrollbar.trough image $I(hor-basic) \
|
||||||
|
-sticky ew
|
||||||
|
|
||||||
|
ttk::style element create Horizontal.Scrollbar.thumb \
|
||||||
|
image [list $I(hor-accent) \
|
||||||
|
disabled $I(hor-basic) \
|
||||||
|
pressed $I(hor-hover) \
|
||||||
|
active $I(hor-hover) \
|
||||||
|
] -sticky ew
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Scrollbar.trough image $I(vert-basic) \
|
||||||
|
-sticky ns
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Scrollbar.thumb \
|
||||||
|
image [list $I(vert-accent) \
|
||||||
|
disabled $I(vert-basic) \
|
||||||
|
pressed $I(vert-hover) \
|
||||||
|
active $I(vert-hover) \
|
||||||
|
] -sticky ns
|
||||||
|
|
||||||
|
# Scale
|
||||||
|
ttk::style element create Horizontal.Scale.trough image $I(scale-hor) \
|
||||||
|
-border 5 -padding 0
|
||||||
|
|
||||||
|
ttk::style element create Horizontal.Scale.slider \
|
||||||
|
image [list $I(circle-accent) \
|
||||||
|
disabled $I(circle-basic) \
|
||||||
|
pressed $I(circle-hover) \
|
||||||
|
active $I(circle-hover) \
|
||||||
|
] -sticky {}
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Scale.trough image $I(scale-vert) \
|
||||||
|
-border 5 -padding 0
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Scale.slider \
|
||||||
|
image [list $I(circle-accent) \
|
||||||
|
disabled $I(circle-basic) \
|
||||||
|
pressed $I(circle-hover) \
|
||||||
|
active $I(circle-hover) \
|
||||||
|
] -sticky {}
|
||||||
|
|
||||||
|
# Tickscale
|
||||||
|
ttk::style element create Horizontal.TickScale.trough image $I(scale-hor) \
|
||||||
|
-border 5 -padding 0
|
||||||
|
|
||||||
|
ttk::style element create Horizontal.TickScale.slider \
|
||||||
|
image [list $I(tick-hor-accent) \
|
||||||
|
disabled $I(tick-hor-basic) \
|
||||||
|
pressed $I(tick-hor-hover) \
|
||||||
|
active $I(tick-hor-hover) \
|
||||||
|
] -sticky {}
|
||||||
|
|
||||||
|
ttk::style element create Vertical.TickScale.trough image $I(scale-vert) \
|
||||||
|
-border 5 -padding 0
|
||||||
|
|
||||||
|
ttk::style element create Vertical.TickScale.slider \
|
||||||
|
image [list $I(tick-vert-accent) \
|
||||||
|
disabled $I(tick-vert-basic) \
|
||||||
|
pressed $I(tick-vert-hover) \
|
||||||
|
active $I(tick-vert-hover) \
|
||||||
|
] -sticky {}
|
||||||
|
|
||||||
|
# Progressbar
|
||||||
|
ttk::style element create Horizontal.Progressbar.trough image $I(hor-basic) \
|
||||||
|
-sticky ew
|
||||||
|
|
||||||
|
ttk::style element create Horizontal.Progressbar.pbar image $I(hor-accent) \
|
||||||
|
-sticky ew
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Progressbar.trough image $I(vert-basic) \
|
||||||
|
-sticky ns
|
||||||
|
|
||||||
|
ttk::style element create Vertical.Progressbar.pbar image $I(vert-accent) \
|
||||||
|
-sticky ns
|
||||||
|
|
||||||
|
# Entry
|
||||||
|
ttk::style element create Entry.field \
|
||||||
|
image [list $I(box-basic) \
|
||||||
|
{focus hover} $I(box-accent) \
|
||||||
|
invalid $I(box-invalid) \
|
||||||
|
disabled $I(box-basic) \
|
||||||
|
focus $I(box-accent) \
|
||||||
|
hover $I(box-hover) \
|
||||||
|
] -border 5 -padding {8} -sticky news
|
||||||
|
|
||||||
|
# Combobox
|
||||||
|
ttk::style map TCombobox -selectbackground [list \
|
||||||
|
{!focus} $colors(-selectbg) \
|
||||||
|
{readonly hover} $colors(-selectbg) \
|
||||||
|
{readonly focus} $colors(-selectbg) \
|
||||||
|
]
|
||||||
|
|
||||||
|
ttk::style map TCombobox -selectforeground [list \
|
||||||
|
{!focus} $colors(-selectfg) \
|
||||||
|
{readonly hover} $colors(-selectfg) \
|
||||||
|
{readonly focus} $colors(-selectfg) \
|
||||||
|
]
|
||||||
|
|
||||||
|
ttk::style element create Combobox.field \
|
||||||
|
image [list $I(box-basic) \
|
||||||
|
{readonly disabled} $I(rect-basic) \
|
||||||
|
{readonly pressed} $I(rect-basic) \
|
||||||
|
{readonly focus hover} $I(button-hover) \
|
||||||
|
{readonly focus} $I(button-hover) \
|
||||||
|
{readonly hover} $I(button-hover) \
|
||||||
|
{focus hover} $I(box-accent) \
|
||||||
|
readonly $I(rect-basic) \
|
||||||
|
invalid $I(box-invalid) \
|
||||||
|
disabled $I(box-basic) \
|
||||||
|
focus $I(box-accent) \
|
||||||
|
hover $I(box-hover) \
|
||||||
|
] -border 5 -padding {8}
|
||||||
|
|
||||||
|
ttk::style element create Combobox.button \
|
||||||
|
image [list $I(combo-button-basic) \
|
||||||
|
{!readonly focus} $I(combo-button-focus) \
|
||||||
|
{readonly focus} $I(combo-button-hover) \
|
||||||
|
{readonly hover} $I(combo-button-hover)
|
||||||
|
] -border 5 -padding {2 6 6 6}
|
||||||
|
|
||||||
|
ttk::style element create Combobox.arrow image $I(down) \
|
||||||
|
-width 15 -sticky e
|
||||||
|
|
||||||
|
# Spinbox
|
||||||
|
ttk::style element create Spinbox.field \
|
||||||
|
image [list $I(box-basic) \
|
||||||
|
invalid $I(box-invalid) \
|
||||||
|
disabled $I(box-basic) \
|
||||||
|
focus $I(box-accent) \
|
||||||
|
hover $I(box-hover) \
|
||||||
|
] -border 5 -padding {8} -sticky news
|
||||||
|
|
||||||
|
ttk::style element create Spinbox.uparrow \
|
||||||
|
image [list $I(up) \
|
||||||
|
disabled $I(up) \
|
||||||
|
pressed $I(up-accent) \
|
||||||
|
active $I(up-accent) \
|
||||||
|
] -border 4 -width 15 -sticky e
|
||||||
|
|
||||||
|
ttk::style element create Spinbox.downarrow \
|
||||||
|
image [list $I(down) \
|
||||||
|
disabled $I(down) \
|
||||||
|
pressed $I(down-accent) \
|
||||||
|
active $I(down-accent) \
|
||||||
|
] -border 4 -width 15 -sticky e
|
||||||
|
|
||||||
|
ttk::style element create Spinbox.button \
|
||||||
|
image [list $I(combo-button-basic) \
|
||||||
|
{!readonly focus} $I(combo-button-focus) \
|
||||||
|
{readonly focus} $I(combo-button-hover) \
|
||||||
|
{readonly hover} $I(combo-button-hover)
|
||||||
|
] -border 5 -padding {2 6 6 6}
|
||||||
|
|
||||||
|
# Sizegrip
|
||||||
|
ttk::style element create Sizegrip.sizegrip image $I(size) \
|
||||||
|
-sticky ewns
|
||||||
|
|
||||||
|
# Separator
|
||||||
|
ttk::style element create Horizontal.separator image $I(separator)
|
||||||
|
|
||||||
|
ttk::style element create Vertical.separator image $I(separator)
|
||||||
|
|
||||||
|
# Card
|
||||||
|
ttk::style element create Card.field image $I(card) \
|
||||||
|
-border 10 -padding 4 -sticky news
|
||||||
|
|
||||||
|
# Labelframe
|
||||||
|
ttk::style element create Labelframe.border image $I(card) \
|
||||||
|
-border 5 -padding 4 -sticky news
|
||||||
|
|
||||||
|
# Notebook
|
||||||
|
ttk::style element create Notebook.client \
|
||||||
|
image $I(notebook) -border 5
|
||||||
|
|
||||||
|
ttk::style element create Notebook.tab \
|
||||||
|
image [list $I(tab-disabled) \
|
||||||
|
selected $I(tab-basic) \
|
||||||
|
active $I(tab-hover) \
|
||||||
|
] -border 5 -padding {14 4}
|
||||||
|
|
||||||
|
# Treeview
|
||||||
|
ttk::style element create Treeview.field image $I(card) \
|
||||||
|
-border 5
|
||||||
|
|
||||||
|
ttk::style element create Treeheading.cell \
|
||||||
|
image [list $I(tree-basic) \
|
||||||
|
pressed $I(tree-pressed)
|
||||||
|
] -border 5 -padding 4 -sticky ewns
|
||||||
|
|
||||||
|
ttk::style element create Treeitem.indicator \
|
||||||
|
image [list $I(right) \
|
||||||
|
user2 $I(empty) \
|
||||||
|
user1 $I(down) \
|
||||||
|
] -width 26 -sticky {}
|
||||||
|
|
||||||
|
ttk::style configure Treeview -background $colors(-bg)
|
||||||
|
ttk::style configure Treeview.Item -padding {2 0 0 0}
|
||||||
|
ttk::style map Treeview \
|
||||||
|
-background [list selected #ccc] \
|
||||||
|
-foreground [list selected $colors(-fg)]
|
||||||
|
|
||||||
|
# Panedwindow
|
||||||
|
# Insane hack to remove clam's ugly sash
|
||||||
|
ttk::style configure Sash -gripcount 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 346 B |
|
After Width: | Height: | Size: 319 B |
|
After Width: | Height: | Size: 329 B |
|
After Width: | Height: | Size: 285 B |
|
After Width: | Height: | Size: 326 B |
|
After Width: | Height: | Size: 444 B |
|
After Width: | Height: | Size: 442 B |
|
After Width: | Height: | Size: 390 B |
|
After Width: | Height: | Size: 451 B |
|
After Width: | Height: | Size: 314 B |
|
After Width: | Height: | Size: 281 B |
|
After Width: | Height: | Size: 319 B |
|
After Width: | Height: | Size: 440 B |
|
After Width: | Height: | Size: 128 B |
|
After Width: | Height: | Size: 429 B |
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 299 B |
|
After Width: | Height: | Size: 234 B |
|
After Width: | Height: | Size: 271 B |
|
After Width: | Height: | Size: 130 B |
|
After Width: | Height: | Size: 153 B |
|
After Width: | Height: | Size: 157 B |
|
After Width: | Height: | Size: 154 B |
|
After Width: | Height: | Size: 389 B |
|
After Width: | Height: | Size: 547 B |
|
After Width: | Height: | Size: 663 B |
|
After Width: | Height: | Size: 635 B |
|
After Width: | Height: | Size: 538 B |
|
After Width: | Height: | Size: 649 B |
|
After Width: | Height: | Size: 508 B |
|
After Width: | Height: | Size: 598 B |
|
After Width: | Height: | Size: 554 B |