mirror of
https://github.com/alhan/noteki.git
synced 2026-08-23 05:30:19 +00:00
- Modern sticky notes app for Windows - PySide6 full-screen transparent canvas - System tray integration, global Alt+N hotkey - Session management, undo/redo, auto-save - Custom color palette with dynamic contrast - Pin notes always-on-top, Tab navigation - Windows Named Mutex single-instance guard
155 lines
6.1 KiB
Python
155 lines
6.1 KiB
Python
"""
|
||
constants.py — Sticky Canvas uygulama sabitleri
|
||
"""
|
||
|
||
import os
|
||
|
||
# ─── Uygulama Bilgisi ───────────────────────────────────────────────
|
||
APP_NAME = "Noteki"
|
||
APP_VERSION = "1.0"
|
||
LOCK_FILE_NAME = "noteki.lock"
|
||
|
||
# ─── Dosya Yolları ──────────────────────────────────────────────────
|
||
APP_DATA_DIR = os.path.join(os.environ.get("APPDATA", os.path.expanduser("~")), "Noteki")
|
||
SESSION_FILE = os.path.join(APP_DATA_DIR, "session.json")
|
||
SESSION_BACKUP_FILE = os.path.join(APP_DATA_DIR, "session.backup.json")
|
||
SETTINGS_FILE = os.path.join(APP_DATA_DIR, "settings.json")
|
||
LOGS_DIR = os.path.join(APP_DATA_DIR, "logs")
|
||
|
||
# ─── Not Boyutları ──────────────────────────────────────────────────
|
||
NOTE_DEFAULT_WIDTH = 220
|
||
NOTE_DEFAULT_HEIGHT = 180
|
||
NOTE_MIN_WIDTH = 150
|
||
NOTE_MIN_HEIGHT = 100
|
||
NOTE_MAX_WIDTH = 600
|
||
NOTE_MAX_HEIGHT = 500
|
||
NOTE_CASCADE_OFFSET = 20 # Yeni not konumu için kaskad kayma px
|
||
NOTE_MAX_COUNT = 50 # Maksimum not sayısı
|
||
NOTE_CHAR_LIMIT = 2000 # Maksimum karakter sayısı
|
||
|
||
# ─── Renk Paleti ────────────────────────────────────────────────────
|
||
NOTE_COLORS = {
|
||
"Sarı": "#FFF9C4",
|
||
"Yeşil": "#C8E6C9",
|
||
"Mavi": "#BBDEFB",
|
||
"Pembe": "#F8BBD0",
|
||
"Mor": "#E1BEE7",
|
||
"Turuncu": "#FFE0B2",
|
||
}
|
||
NOTE_COLOR_KEYS = list(NOTE_COLORS.keys())
|
||
NOTE_DEFAULT_COLOR = "#FFF9C4" # Sarı
|
||
|
||
# Her renk için metin ve accent rengi dinamik olarak hesaplanir:
|
||
# get_contrast_text_color() → okunabilir metin rengi
|
||
# get_dynamic_accent_color() → aktif not vurgu rengi
|
||
|
||
# ─── Varsayılan Ayarlar ─────────────────────────────────────────────
|
||
DEFAULT_FONT_FAMILY = "Segoe UI"
|
||
DEFAULT_FONT_SIZE = 14
|
||
DEFAULT_HOTKEY = "Alt+N"
|
||
DEFAULT_AUTO_START = False
|
||
|
||
# ─── Undo ───────────────────────────────────────────────────────────
|
||
UNDO_CAPACITY = 10
|
||
|
||
# ─── Auto-Save ──────────────────────────────────────────────────────
|
||
AUTOSAVE_DELAY_MS = 500 # Debounce süresi (ms)
|
||
|
||
# ─── Sürükleme ──────────────────────────────────────────────────────
|
||
DRAG_OPACITY = 0.85 # Sürükleme sırasında opaklık
|
||
|
||
# ─── "+" Butonu ─────────────────────────────────────────────────────
|
||
ADD_BUTTON_SIZE = 48
|
||
ADD_BUTTON_MARGIN = 24 # Sağ alt köşeden uzaklık
|
||
|
||
# ─── Windows Registry ───────────────────────────────────────────────
|
||
REGISTRY_RUN_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run"
|
||
REGISTRY_APP_KEY = APP_NAME
|
||
|
||
def get_contrast_text_color(hex_str: str) -> str:
|
||
"""Arka plan rengine (hex_str) göre en yüksek kontrastlı metin rengini (#1A1A1A veya #FFFFFF) döner."""
|
||
try:
|
||
hex_str = hex_str.lstrip('#')
|
||
r, g, b = int(hex_str[0:2], 16), int(hex_str[2:4], 16), int(hex_str[4:6], 16)
|
||
# Parlaklık (Luminance) formülü
|
||
l = 0.299 * r + 0.587 * g + 0.114 * b
|
||
return "#1A1A1A" if l > 130 else "#FFFFFF"
|
||
except Exception:
|
||
return "#1A1A1A"
|
||
|
||
def get_dynamic_accent_color(hex_str: str) -> str:
|
||
"""
|
||
Arka plan rengine (hex_str) göre dinamik olarak bir accent (border/seçim) rengi hesaplar.
|
||
Açık renkler için rengi koyulaştırır/doygunlaştırır, koyu renkler için açar.
|
||
"""
|
||
try:
|
||
hex_str = hex_str.lstrip('#')
|
||
r, g, b = int(hex_str[0:2], 16), int(hex_str[2:4], 16), int(hex_str[4:6], 16)
|
||
|
||
# RGB to HSV conversion
|
||
r_f, g_f, b_f = r / 255.0, g / 255.0, b / 255.0
|
||
cmax = max(r_f, g_f, b_f)
|
||
cmin = min(r_f, g_f, b_f)
|
||
diff = cmax - cmin
|
||
|
||
# Hue
|
||
if cmax == cmin:
|
||
h = 0
|
||
elif cmax == r_f:
|
||
h = (60 * ((g_f - b_f) / diff) + 360) % 360
|
||
elif cmax == g_f:
|
||
h = (60 * ((b_f - r_f) / diff) + 120) % 360
|
||
else:
|
||
h = (60 * ((r_f - g_f) / diff) + 240) % 360
|
||
|
||
# Saturation
|
||
s = 0 if cmax == 0 else (diff / cmax)
|
||
|
||
# Value
|
||
v = cmax
|
||
|
||
# Parlaklık
|
||
l = 0.299 * r + 0.587 * g + 0.114 * b
|
||
|
||
if l > 130:
|
||
# Açık renk: Rengi koyulaştır ve doygunluğu artır
|
||
v = max(0.0, v - 0.25)
|
||
s = min(1.0, s + 0.3)
|
||
else:
|
||
# Koyu renk: Rengi aç ve doygunluğu azalt
|
||
v = min(1.0, v + 0.25)
|
||
s = max(0.0, s - 0.2)
|
||
|
||
# HSV to RGB conversion
|
||
c = v * s
|
||
x = c * (1 - abs((h / 60) % 2 - 1))
|
||
m = v - c
|
||
|
||
if 0 <= h < 60:
|
||
r_f, g_f, b_f = c, x, 0
|
||
elif 60 <= h < 120:
|
||
r_f, g_f, b_f = x, c, 0
|
||
elif 120 <= h < 180:
|
||
r_f, g_f, b_f = 0, c, x
|
||
elif 180 <= h < 240:
|
||
r_f, g_f, b_f = 0, x, c
|
||
elif 240 <= h < 300:
|
||
r_f, g_f, b_f = x, 0, c
|
||
else:
|
||
r_f, g_f, b_f = c, 0, x
|
||
|
||
r = int((r_f + m) * 255)
|
||
g = int((g_f + m) * 255)
|
||
b = int((b_f + m) * 255)
|
||
|
||
# Sınır kontrolü
|
||
r = max(0, min(255, r))
|
||
g = max(0, min(255, g))
|
||
b = max(0, min(255, b))
|
||
|
||
return f"#{r:02X}{g:02X}{b:02X}"
|
||
except Exception:
|
||
# Hata durumunda güvenli bir gri ton
|
||
return "#7F7F7F"
|
||
|