Saba-python/secure_sms/ui/core.py

109 lines
3.2 KiB
Python

import os
import re
from tkinter import TclError
import customtkinter as ctk
try:
import arabic_reshaper
from bidi.algorithm import get_display
except ImportError:
arabic_reshaper = None
get_display = None
ctk.set_appearance_mode("light")
ctk.set_default_color_theme("blue")
PRIMARY = "#175B4B"
PRIMARY_DARK = "#0E4236"
PRIMARY_SOFT = "#DFF1E8"
ACCENT = "#E8A04D"
ACCENT_DARK = "#C97E2D"
BACKGROUND = "#F5EFE7"
CARD = "#FFFDFC"
SURFACE = "#FBF7F2"
INPUT_BG = "#FFFCF8"
TEXT = "#16312A"
MUTED = "#6B7A77"
DANGER = "#B6465F"
WARNING = "#9A6C3C"
BORDER = "#E5DCCE"
KEYBOARD_BG = "#D4DCE2"
KEY_FACE = "#FFFFFF"
KEY_MUTED = "#BCC1C9"
KEY_TEXT = "#000000"
SIDEBAR = "#1B5A4A"
SIDEBAR_SOFT = "#245E4E"
FONT_BODY = "Tahoma" if os.name == "nt" else "DejaVu Sans"
FONT_TITLE = "Tahoma" if os.name == "nt" else "DejaVu Sans"
RTL_PATTERN = re.compile(r"[\u0600-\u06FF]")
def ui_text(value):
if not isinstance(value, str) or not value:
return value
if arabic_reshaper is None or get_display is None or not RTL_PATTERN.search(value):
return value
return get_display(arabic_reshaper.reshape(value))
class _RTLTextMixin:
@staticmethod
def _normalize_kwargs(kwargs):
normalized = dict(kwargs)
if "text" in normalized:
normalized["text"] = ui_text(normalized["text"])
if "placeholder_text" in normalized:
normalized["placeholder_text"] = ui_text(normalized["placeholder_text"])
if "label_text" in normalized:
normalized["label_text"] = ui_text(normalized["label_text"])
return normalized
class RTLLabel(_RTLTextMixin, ctk.CTkLabel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **self._normalize_kwargs(kwargs))
def configure(self, require_redraw=False, **kwargs):
return super().configure(require_redraw=require_redraw, **self._normalize_kwargs(kwargs))
class RTLButton(_RTLTextMixin, ctk.CTkButton):
def __init__(self, *args, **kwargs):
kwargs.setdefault("corner_radius", 16)
super().__init__(*args, **self._normalize_kwargs(kwargs))
def configure(self, require_redraw=False, **kwargs):
return super().configure(require_redraw=require_redraw, **self._normalize_kwargs(kwargs))
class RTLEntry(_RTLTextMixin, ctk.CTkEntry):
def __init__(self, *args, **kwargs):
kwargs.setdefault("justify", "right")
kwargs.setdefault("fg_color", INPUT_BG)
kwargs.setdefault("border_color", BORDER)
kwargs.setdefault("corner_radius", 16)
super().__init__(*args, **self._normalize_kwargs(kwargs))
def configure(self, require_redraw=False, **kwargs):
return super().configure(require_redraw=require_redraw, **self._normalize_kwargs(kwargs))
class RTLTextbox(ctk.CTkTextbox):
def insert(self, index, text, *tags):
return super().insert(index, ui_text(text), *tags)
class RTLScrollableFrame(_RTLTextMixin, ctk.CTkScrollableFrame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **self._normalize_kwargs(kwargs))
def configure(self, require_redraw=False, **kwargs):
return super().configure(require_redraw=require_redraw, **self._normalize_kwargs(kwargs))