Files
UmaCardApplication/gui/effects_view.py

140 lines
5.5 KiB
Python

"""
Effects Search View - Search for effects across all owned cards
"""
import tkinter as tk
from tkinter import ttk, messagebox
import sys
import os
import re
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from db.db_queries import search_owned_effects
from gui.theme import (
BG_DARK, BG_MEDIUM, BG_LIGHT, BG_HIGHLIGHT,
ACCENT_PRIMARY, ACCENT_SECONDARY, ACCENT_SUCCESS, ACCENT_TERTIARY,
TEXT_PRIMARY, TEXT_SECONDARY, TEXT_MUTED,
FONT_HEADER, FONT_SUBHEADER, FONT_BODY, FONT_BODY_BOLD, FONT_SMALL,
create_styled_button, create_styled_entry
)
from utils import resolve_image_path
class EffectsFrame(ttk.Frame):
"""Frame for searching effects across owned cards"""
def __init__(self, parent):
super().__init__(parent)
self.create_widgets()
def create_widgets(self):
"""Create the effects search interface"""
# Header / Search Bar
header_frame = tk.Frame(self, bg=BG_DARK)
header_frame.pack(fill=tk.X, padx=20, pady=15)
# Search container
search_container = tk.Frame(header_frame, bg=BG_DARK)
search_container.pack(fill=tk.X)
tk.Label(search_container, text="🔍 Search Effect:",
font=FONT_HEADER, bg=BG_DARK, fg=TEXT_PRIMARY).pack(side=tk.LEFT, padx=(0, 10))
self.search_var = tk.StringVar()
self.search_entry = create_styled_entry(search_container, textvariable=self.search_var)
self.search_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 10))
self.search_entry.bind('<Return>', lambda e: self.perform_search())
search_btn = create_styled_button(search_container, text="Search",
command=self.perform_search, style_type='primary')
search_btn.pack(side=tk.LEFT)
# Example/Help text
help_frame = tk.Frame(header_frame, bg=BG_DARK)
help_frame.pack(fill=tk.X, pady=(5, 0))
tk.Label(help_frame, text="Examples: Friendship, Motivation, Race Bonus, Skill Pt",
font=FONT_SMALL, bg=BG_DARK, fg=TEXT_MUTED).pack(side=tk.LEFT)
# Results Area
results_frame = ttk.LabelFrame(self, text=" Search Results (Owned Cards) ", padding=10)
results_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=(0, 20))
# Treeview
columns = ('card', 'level', 'current_value', 'effect_name')
self.tree = ttk.Treeview(results_frame, columns=columns, show='headings', selectmode='browse')
self.tree.heading('card', text='Card Name', anchor='w')
self.tree.heading('level', text='Level', anchor='center')
self.tree.heading('current_value', text='Value', anchor='center')
self.tree.heading('effect_name', text='Effect Name', anchor='w')
self.tree.column('card', width=250)
self.tree.column('level', width=60, anchor='center')
self.tree.column('current_value', width=80, anchor='center')
self.tree.column('effect_name', width=150)
scrollbar = ttk.Scrollbar(results_frame, orient=tk.VERTICAL, command=self.tree.yview)
self.tree.configure(yscrollcommand=scrollbar.set)
self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# Status Label
self.status_label = tk.Label(results_frame, text="", bg=BG_MEDIUM, fg=TEXT_SECONDARY, font=FONT_SMALL)
self.status_label.pack(side=tk.BOTTOM, fill=tk.X, pady=(5, 0))
def parse_value(self, value_str):
"""Parse effect value string to float for sorting"""
try:
# Extract number from string (e.g. "20%" -> 20, "+15" -> 15)
# Remove non-numeric characters except . and -
clean = re.sub(r'[^\d.-]', '', str(value_str))
return float(clean)
except:
return -999999.0 # Sort to bottom if invalid
def perform_search(self):
"""Execute search and update results"""
term = self.search_var.get().strip()
if not term:
messagebox.showwarning("Search", "Please enter a search term")
return
# clear current
for item in self.tree.get_children():
self.tree.delete(item)
# Query DB
results = search_owned_effects(term)
if not results:
self.status_label.config(text="No matching effects found among owned cards.")
return
# Process and Sort
# Row: (card_id, card_name, image_path, effect_name, effect_value, level)
processed_results = []
for r in results:
val_num = self.parse_value(r[4])
processed_results.append({
'data': r,
'sort_val': val_num
})
# Sort by value descending
processed_results.sort(key=lambda x: x['sort_val'], reverse=True)
# Populate Tree
for item in processed_results:
r = item['data']
#Columns: card, level, current_value, effect_name
values = (r[1], f"Lv {r[5]}", r[4], r[3])
self.tree.insert('', tk.END, values=values)
self.status_label.config(text=f"Found {len(processed_results)} owned cards with matching effects.")
# Compatibility methods for main_window integration (empty as we don't need them anymore)
def set_card(self, card_id):
pass