Changed Hints and Skills to Skill Search
This commit is contained in:
@@ -700,3 +700,102 @@ def get_database_stats():
|
|||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
return stats
|
return stats
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Skill Search Queries
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
def get_all_unique_skills():
|
||||||
|
"""Get a sorted list of all unique skills from hints and events"""
|
||||||
|
conn = get_conn()
|
||||||
|
cur = conn.cursor()
|
||||||
|
|
||||||
|
# Get skills from hints
|
||||||
|
cur.execute("SELECT DISTINCT hint_name FROM support_hints")
|
||||||
|
hint_skills = {row[0] for row in cur.fetchall() if row[0]}
|
||||||
|
|
||||||
|
# Get skills from events
|
||||||
|
cur.execute("SELECT DISTINCT skill_name FROM event_skills")
|
||||||
|
event_skills = {row[0] for row in cur.fetchall() if row[0]}
|
||||||
|
|
||||||
|
# Combine and sort
|
||||||
|
all_skills = sorted(list(hint_skills.union(event_skills)))
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
return all_skills
|
||||||
|
|
||||||
|
def get_cards_with_skill(skill_name):
|
||||||
|
"""
|
||||||
|
Find all cards that have a specific skill.
|
||||||
|
Returns list of dicts:
|
||||||
|
{
|
||||||
|
'card_id': int,
|
||||||
|
'name': str,
|
||||||
|
'rarity': str,
|
||||||
|
'type': str,
|
||||||
|
'image_path': str,
|
||||||
|
'source': str ('Hint' or 'Event: [Name]'),
|
||||||
|
'details': str (description or event name)
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
conn = get_conn()
|
||||||
|
cur = conn.cursor()
|
||||||
|
|
||||||
|
results = []
|
||||||
|
seen_entries = set() # To avoid duplicates if same skill in multiple events
|
||||||
|
|
||||||
|
# 1. Check Hints
|
||||||
|
cur.execute("""
|
||||||
|
SELECT sc.card_id, sc.name, sc.rarity, sc.card_type, sc.image_path, sh.hint_description
|
||||||
|
FROM support_hints sh
|
||||||
|
JOIN support_cards sc ON sh.card_id = sc.card_id
|
||||||
|
WHERE sh.hint_name = ?
|
||||||
|
""", (skill_name,))
|
||||||
|
|
||||||
|
for row in cur.fetchall():
|
||||||
|
entry_key = (row[0], 'Hint')
|
||||||
|
if entry_key not in seen_entries:
|
||||||
|
results.append({
|
||||||
|
'card_id': row[0],
|
||||||
|
'name': row[1],
|
||||||
|
'rarity': row[2],
|
||||||
|
'type': row[3],
|
||||||
|
'image_path': row[4],
|
||||||
|
'source': 'Training Hint',
|
||||||
|
'details': row[5] or "Random hint event"
|
||||||
|
})
|
||||||
|
seen_entries.add(entry_key)
|
||||||
|
|
||||||
|
# 2. Check Event Skills
|
||||||
|
cur.execute("""
|
||||||
|
SELECT sc.card_id, sc.name, sc.rarity, sc.card_type, sc.image_path, se.event_name
|
||||||
|
FROM event_skills es
|
||||||
|
JOIN support_events se ON es.event_id = se.event_id
|
||||||
|
JOIN support_cards sc ON se.card_id = sc.card_id
|
||||||
|
WHERE es.skill_name = ?
|
||||||
|
""", (skill_name,))
|
||||||
|
|
||||||
|
for row in cur.fetchall():
|
||||||
|
# Clean event name if it has newlines or excessive spaces
|
||||||
|
event_name = row[5].replace('\n', ' ').strip()
|
||||||
|
entry_key = (row[0], f'Event: {event_name}')
|
||||||
|
|
||||||
|
if entry_key not in seen_entries:
|
||||||
|
results.append({
|
||||||
|
'card_id': row[0],
|
||||||
|
'name': row[1],
|
||||||
|
'rarity': row[2],
|
||||||
|
'type': row[3],
|
||||||
|
'image_path': row[4],
|
||||||
|
'source': 'Event',
|
||||||
|
'details': event_name
|
||||||
|
})
|
||||||
|
seen_entries.add(entry_key)
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
# Sort by Rarity (SSR first), then Name
|
||||||
|
rarity_map = {'SSR': 3, 'SR': 2, 'R': 1}
|
||||||
|
results.sort(key=lambda x: (rarity_map.get(x['rarity'], 0), x['name']), reverse=True)
|
||||||
|
|
||||||
|
return results
|
||||||
|
|||||||
@@ -1,180 +1,200 @@
|
|||||||
"""
|
"""
|
||||||
Hints and Skills View - Display support hints and event skills
|
Skill Search View - Find cards by the skills they teach
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
from PIL import Image, ImageTk
|
||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
from db.db_queries import get_hints, get_events, get_all_event_skills, get_card_by_id
|
from db.db_queries import get_all_unique_skills, get_cards_with_skill
|
||||||
|
from utils import resolve_image_path
|
||||||
from gui.theme import (
|
from gui.theme import (
|
||||||
BG_DARK, BG_MEDIUM, BG_LIGHT,
|
BG_DARK, BG_MEDIUM, BG_LIGHT, BG_HIGHLIGHT,
|
||||||
ACCENT_PRIMARY, ACCENT_SECONDARY, ACCENT_TERTIARY, ACCENT_SUCCESS,
|
ACCENT_PRIMARY, ACCENT_SECONDARY, ACCENT_TERTIARY,
|
||||||
TEXT_PRIMARY, TEXT_SECONDARY, TEXT_MUTED,
|
TEXT_PRIMARY, TEXT_SECONDARY, TEXT_MUTED,
|
||||||
FONT_HEADER, FONT_SUBHEADER, FONT_BODY, FONT_BODY_BOLD, FONT_SMALL,
|
FONT_HEADER, FONT_SUBHEADER, FONT_BODY, FONT_BODY_BOLD, FONT_SMALL,
|
||||||
create_styled_text, create_card_frame
|
create_card_frame, get_type_icon, create_styled_button
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class HintsSkillsFrame(ttk.Frame):
|
class SkillSearchFrame(ttk.Frame):
|
||||||
"""Frame for viewing support hints and event skills"""
|
"""Frame for searching skills and finding cards that have them"""
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.current_card_id = None
|
self.all_skills = []
|
||||||
self.current_card_name = None
|
self.icon_cache = {}
|
||||||
|
|
||||||
self.create_widgets()
|
self.create_widgets()
|
||||||
|
self.load_skills()
|
||||||
|
|
||||||
def create_widgets(self):
|
def create_widgets(self):
|
||||||
"""Create the hints and skills interface"""
|
"""Create the skill search interface"""
|
||||||
# Header
|
# Main split container
|
||||||
header_frame = tk.Frame(self, bg=BG_DARK)
|
main_pane = ttk.PanedWindow(self, orient=tk.HORIZONTAL)
|
||||||
header_frame.pack(fill=tk.X, padx=20, pady=15)
|
main_pane.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
|
||||||
|
|
||||||
self.card_label = tk.Label(header_frame,
|
# === Left Panel: Skill List ===
|
||||||
text="💡 Select a card from the Card List tab",
|
left_frame = tk.Frame(main_pane, bg=BG_DARK, width=300)
|
||||||
font=FONT_HEADER, bg=BG_DARK, fg=ACCENT_PRIMARY)
|
main_pane.add(left_frame, weight=1)
|
||||||
self.card_label.pack(side=tk.LEFT)
|
|
||||||
|
|
||||||
# Main content with two columns
|
# Search Header
|
||||||
content_frame = tk.Frame(self, bg=BG_DARK)
|
header = tk.Frame(left_frame, bg=BG_DARK)
|
||||||
content_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=(0, 15))
|
header.pack(fill=tk.X, pady=(0, 10))
|
||||||
|
tk.Label(header, text="🔍 Search Skills", font=FONT_HEADER,
|
||||||
# Left column: Hints
|
|
||||||
left_container = tk.Frame(content_frame, bg=BG_DARK)
|
|
||||||
left_container.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))
|
|
||||||
|
|
||||||
hints_header = tk.Frame(left_container, bg=BG_DARK)
|
|
||||||
hints_header.pack(fill=tk.X, pady=(0, 8))
|
|
||||||
tk.Label(hints_header, text="🎯 Training Hints", font=FONT_SUBHEADER,
|
|
||||||
bg=BG_DARK, fg=TEXT_PRIMARY).pack(side=tk.LEFT)
|
bg=BG_DARK, fg=TEXT_PRIMARY).pack(side=tk.LEFT)
|
||||||
|
|
||||||
hints_frame = create_card_frame(left_container)
|
# Search Entry
|
||||||
hints_frame.pack(fill=tk.BOTH, expand=True)
|
self.search_var = tk.StringVar()
|
||||||
|
self.search_var.trace('w', self.filter_skills)
|
||||||
|
|
||||||
self.hints_text = create_styled_text(hints_frame, height=18)
|
search_entry = ttk.Entry(left_frame, textvariable=self.search_var)
|
||||||
self.hints_text.pack(fill=tk.BOTH, expand=True, padx=2, pady=2)
|
search_entry.pack(fill=tk.X, padx=(0, 5), pady=(0, 10))
|
||||||
self.hints_text.config(state=tk.DISABLED)
|
|
||||||
|
|
||||||
# Configure tags for hints
|
# Skill Listbox
|
||||||
self.hints_text.tag_configure('header', font=FONT_SUBHEADER, foreground=ACCENT_PRIMARY)
|
list_container = create_card_frame(left_frame)
|
||||||
self.hints_text.tag_configure('skill', foreground=ACCENT_TERTIARY, font=FONT_BODY_BOLD)
|
list_container.pack(fill=tk.BOTH, expand=True)
|
||||||
self.hints_text.tag_configure('desc', foreground=TEXT_MUTED)
|
|
||||||
self.hints_text.tag_configure('number', foreground=ACCENT_SECONDARY)
|
|
||||||
|
|
||||||
# Right column: Events and Skills
|
scrollbar = ttk.Scrollbar(list_container, orient=tk.VERTICAL)
|
||||||
right_container = tk.Frame(content_frame, bg=BG_DARK)
|
self.skill_listbox = tk.Listbox(list_container,
|
||||||
right_container.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
|
bg=BG_MEDIUM, fg=TEXT_SECONDARY,
|
||||||
|
selectbackground=ACCENT_PRIMARY,
|
||||||
|
selectforeground=TEXT_PRIMARY,
|
||||||
|
highlightthickness=0, bd=0,
|
||||||
|
font=FONT_BODY,
|
||||||
|
yscrollcommand=scrollbar.set)
|
||||||
|
|
||||||
events_header = tk.Frame(right_container, bg=BG_DARK)
|
scrollbar.config(command=self.skill_listbox.yview)
|
||||||
events_header.pack(fill=tk.X, pady=(0, 8))
|
|
||||||
tk.Label(events_header, text="📅 Training Events & Skills", font=FONT_SUBHEADER,
|
|
||||||
bg=BG_DARK, fg=TEXT_PRIMARY).pack(side=tk.LEFT)
|
|
||||||
|
|
||||||
events_frame = create_card_frame(right_container)
|
self.skill_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=2, pady=2)
|
||||||
events_frame.pack(fill=tk.BOTH, expand=True)
|
|
||||||
|
|
||||||
tree_container = tk.Frame(events_frame, bg=BG_MEDIUM)
|
|
||||||
tree_container.pack(fill=tk.BOTH, expand=True, padx=2, pady=2)
|
|
||||||
|
|
||||||
# Treeview for events
|
|
||||||
self.events_tree = ttk.Treeview(tree_container, columns=('event', 'skills'), show='tree headings')
|
|
||||||
self.events_tree.heading('#0', text='')
|
|
||||||
self.events_tree.heading('event', text='Event/Skill')
|
|
||||||
self.events_tree.heading('skills', text='Details')
|
|
||||||
|
|
||||||
self.events_tree.column('#0', width=35)
|
|
||||||
self.events_tree.column('event', width=240)
|
|
||||||
self.events_tree.column('skills', width=180)
|
|
||||||
|
|
||||||
scrollbar = ttk.Scrollbar(tree_container, orient=tk.VERTICAL, command=self.events_tree.yview)
|
|
||||||
self.events_tree.configure(yscrollcommand=scrollbar.set)
|
|
||||||
|
|
||||||
self.events_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
||||||
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
||||||
|
|
||||||
# Summary section at bottom
|
self.skill_listbox.bind('<<ListboxSelect>>', self.on_skill_selected)
|
||||||
summary_frame = tk.Frame(self, bg=BG_MEDIUM, padx=15, pady=10)
|
|
||||||
summary_frame.pack(fill=tk.X, padx=20, pady=(0, 10))
|
|
||||||
|
|
||||||
self.summary_label = tk.Label(summary_frame, text="", font=FONT_SMALL,
|
# === Right Panel: Results ===
|
||||||
bg=BG_MEDIUM, fg=TEXT_SECONDARY)
|
right_frame = tk.Frame(main_pane, bg=BG_DARK)
|
||||||
self.summary_label.pack()
|
main_pane.add(right_frame, weight=3)
|
||||||
|
|
||||||
|
# Result Header
|
||||||
|
self.result_header = tk.Label(right_frame, text="Select a skill to see who has it",
|
||||||
|
font=FONT_HEADER, bg=BG_DARK, fg=ACCENT_TERTIARY)
|
||||||
|
self.result_header.pack(anchor='w', pady=(0, 15), padx=10)
|
||||||
|
|
||||||
|
# Results Treeview
|
||||||
|
tree_frame = create_card_frame(right_frame)
|
||||||
|
tree_frame.pack(fill=tk.BOTH, expand=True, padx=10)
|
||||||
|
|
||||||
|
cols = ('name', 'rarity', 'type', 'source', 'details')
|
||||||
|
self.tree = ttk.Treeview(tree_frame, columns=cols, show='tree headings',
|
||||||
|
style="Treeview")
|
||||||
|
|
||||||
|
self.tree.heading('#0', text='')
|
||||||
|
self.tree.heading('name', text='Card Name')
|
||||||
|
self.tree.heading('rarity', text='Rarity')
|
||||||
|
self.tree.heading('type', text='Type')
|
||||||
|
self.tree.heading('source', text='Source')
|
||||||
|
self.tree.heading('details', text='Details')
|
||||||
|
|
||||||
|
self.tree.column('#0', width=50, anchor='center')
|
||||||
|
self.tree.column('name', width=180)
|
||||||
|
self.tree.column('rarity', width=50, anchor='center')
|
||||||
|
self.tree.column('type', width=80, anchor='center')
|
||||||
|
self.tree.column('source', width=100)
|
||||||
|
self.tree.column('details', width=250)
|
||||||
|
|
||||||
|
vsb = ttk.Scrollbar(tree_frame, orient=tk.VERTICAL, command=self.tree.yview)
|
||||||
|
self.tree.configure(yscrollcommand=vsb.set)
|
||||||
|
|
||||||
|
self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=2, pady=2)
|
||||||
|
vsb.pack(side=tk.RIGHT, fill=tk.Y, pady=2)
|
||||||
|
|
||||||
|
# Stats footer
|
||||||
|
self.stats_label = tk.Label(right_frame, text="", font=FONT_SMALL,
|
||||||
|
bg=BG_DARK, fg=TEXT_MUTED)
|
||||||
|
self.stats_label.pack(anchor='e', pady=5, padx=10)
|
||||||
|
|
||||||
|
def load_skills(self):
|
||||||
|
"""Load all unique skills into listbox"""
|
||||||
|
self.all_skills = get_all_unique_skills()
|
||||||
|
self.update_listbox(self.all_skills)
|
||||||
|
|
||||||
|
def update_listbox(self, items):
|
||||||
|
"""Update listbox content"""
|
||||||
|
self.skill_listbox.delete(0, tk.END)
|
||||||
|
for item in items:
|
||||||
|
self.skill_listbox.insert(tk.END, item)
|
||||||
|
|
||||||
|
def filter_skills(self, *args):
|
||||||
|
"""Filter skills based on search text"""
|
||||||
|
search = self.search_var.get().lower()
|
||||||
|
if not search:
|
||||||
|
self.update_listbox(self.all_skills)
|
||||||
|
return
|
||||||
|
|
||||||
|
filtered = [s for s in self.all_skills if search in s.lower()]
|
||||||
|
self.update_listbox(filtered)
|
||||||
|
|
||||||
|
def on_skill_selected(self, event):
|
||||||
|
"""Handle skill selection"""
|
||||||
|
selection = self.skill_listbox.curselection()
|
||||||
|
if not selection:
|
||||||
|
return
|
||||||
|
|
||||||
|
skill_name = self.skill_listbox.get(selection[0])
|
||||||
|
self.show_cards_for_skill(skill_name)
|
||||||
|
|
||||||
|
def show_cards_for_skill(self, skill_name):
|
||||||
|
"""Fetch and display cards with the selected skill"""
|
||||||
|
self.result_header.config(text=f"Cards with skill: {skill_name}")
|
||||||
|
|
||||||
|
# Clear tree
|
||||||
|
for item in self.tree.get_children():
|
||||||
|
self.tree.delete(item)
|
||||||
|
|
||||||
|
cards = get_cards_with_skill(skill_name)
|
||||||
|
|
||||||
|
for card in cards:
|
||||||
|
# Load Icon
|
||||||
|
card_id = card['card_id']
|
||||||
|
img = self.icon_cache.get(card_id)
|
||||||
|
if not img:
|
||||||
|
resolved_path = resolve_image_path(card['image_path'])
|
||||||
|
if resolved_path and os.path.exists(resolved_path):
|
||||||
|
try:
|
||||||
|
pil_img = Image.open(resolved_path)
|
||||||
|
pil_img.thumbnail((32, 32), Image.Resampling.LANCZOS)
|
||||||
|
img = ImageTk.PhotoImage(pil_img)
|
||||||
|
self.icon_cache[card_id] = img
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
type_display = f"{get_type_icon(card['type'])} {card['type']}"
|
||||||
|
|
||||||
|
values = (
|
||||||
|
card['name'],
|
||||||
|
card['rarity'],
|
||||||
|
type_display,
|
||||||
|
card['source'],
|
||||||
|
card['details']
|
||||||
|
)
|
||||||
|
|
||||||
|
if img:
|
||||||
|
self.tree.insert('', tk.END, text='', image=img, values=values)
|
||||||
|
else:
|
||||||
|
self.tree.insert('', tk.END, text='?', values=values)
|
||||||
|
|
||||||
|
self.stats_label.config(text=f"Found {len(cards)} cards")
|
||||||
|
|
||||||
def set_card(self, card_id):
|
def set_card(self, card_id):
|
||||||
"""Load a card's hints and skills"""
|
"""
|
||||||
self.current_card_id = card_id
|
Legacy method compatibility for main window calls.
|
||||||
|
We don't need to do anything here since we are skill-centric now.
|
||||||
# Get card info
|
But main_window might call it when card is selected in tab 1.
|
||||||
card = get_card_by_id(card_id)
|
We could potentially auto-search a skill from that card?
|
||||||
if card:
|
For now, just ignore it.
|
||||||
self.current_card_name = card[1]
|
"""
|
||||||
self.card_label.config(text=f"💡 {self.current_card_name}")
|
pass
|
||||||
|
|
||||||
self.update_hints_display()
|
|
||||||
self.update_events_display()
|
|
||||||
|
|
||||||
def update_hints_display(self):
|
|
||||||
"""Update the hints display"""
|
|
||||||
self.hints_text.config(state=tk.NORMAL)
|
|
||||||
self.hints_text.delete('1.0', tk.END)
|
|
||||||
|
|
||||||
if not self.current_card_id:
|
|
||||||
self.hints_text.insert(tk.END, "No card selected\n\n", 'desc')
|
|
||||||
self.hints_text.insert(tk.END, "Select a card from the Card List tab to view its hints.", 'desc')
|
|
||||||
self.hints_text.config(state=tk.DISABLED)
|
|
||||||
return
|
|
||||||
|
|
||||||
hints = get_hints(self.current_card_id)
|
|
||||||
|
|
||||||
self.hints_text.insert(tk.END, "Training Skills this card can teach:\n\n", 'header')
|
|
||||||
|
|
||||||
if hints:
|
|
||||||
for i, (hint_name, hint_desc) in enumerate(hints, 1):
|
|
||||||
self.hints_text.insert(tk.END, f" {i}. ", 'number')
|
|
||||||
self.hints_text.insert(tk.END, f"{hint_name}\n", 'skill')
|
|
||||||
if hint_desc:
|
|
||||||
self.hints_text.insert(tk.END, f" {hint_desc}\n", 'desc')
|
|
||||||
self.hints_text.insert(tk.END, "\n")
|
|
||||||
else:
|
|
||||||
self.hints_text.insert(tk.END, " No hints/skills data available.\n\n", 'desc')
|
|
||||||
self.hints_text.insert(tk.END, " This may mean:\n", 'desc')
|
|
||||||
self.hints_text.insert(tk.END, " • Card hasn't been scraped yet\n", 'desc')
|
|
||||||
self.hints_text.insert(tk.END, " • Card has no trainable skills\n", 'desc')
|
|
||||||
|
|
||||||
self.hints_text.config(state=tk.DISABLED)
|
|
||||||
|
|
||||||
def update_events_display(self):
|
|
||||||
"""Update the events tree display"""
|
|
||||||
self.events_tree.delete(*self.events_tree.get_children())
|
|
||||||
|
|
||||||
if not self.current_card_id:
|
|
||||||
return
|
|
||||||
|
|
||||||
events = get_events(self.current_card_id)
|
|
||||||
events_with_skills = get_all_event_skills(self.current_card_id)
|
|
||||||
|
|
||||||
# Add events as parent nodes
|
|
||||||
for event_id, event_name, event_type in events:
|
|
||||||
skills = events_with_skills.get(event_name, [])
|
|
||||||
skill_count = f"{len(skills)} skills" if skills else "No skills"
|
|
||||||
|
|
||||||
event_node = self.events_tree.insert('', tk.END, text='📅',
|
|
||||||
values=(event_name, skill_count))
|
|
||||||
|
|
||||||
# Add skills as children
|
|
||||||
for skill in skills:
|
|
||||||
self.events_tree.insert(event_node, tk.END, text='⭐',
|
|
||||||
values=(skill, ''))
|
|
||||||
|
|
||||||
# Update summary
|
|
||||||
hint_count = len(get_hints(self.current_card_id))
|
|
||||||
event_count = len(events)
|
|
||||||
|
|
||||||
self.summary_label.config(
|
|
||||||
text=f"📊 Summary: {hint_count} hints │ {event_count} events"
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|||||||
from db.db_queries import get_database_stats, get_owned_count
|
from db.db_queries import get_database_stats, get_owned_count
|
||||||
from gui.card_view import CardListFrame
|
from gui.card_view import CardListFrame
|
||||||
from gui.effects_view import EffectsFrame
|
from gui.effects_view import EffectsFrame
|
||||||
from gui.hints_skills_view import HintsSkillsFrame
|
from gui.hints_skills_view import SkillSearchFrame
|
||||||
from gui.deck_builder import DeckBuilderFrame
|
from gui.deck_builder import DeckBuilderFrame
|
||||||
from gui.update_dialog import show_update_dialog
|
from gui.update_dialog import show_update_dialog
|
||||||
from gui.theme import (
|
from gui.theme import (
|
||||||
@@ -33,7 +33,7 @@ class MainWindow:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.root = tk.Tk()
|
self.root = tk.Tk()
|
||||||
self.root.title("Umamusume Support Card Manager")
|
self.root.title("Umamusume Support Card Manager")
|
||||||
self.root.geometry("1350x800")
|
self.root.geometry("1400x850") # Slightly larger for new UI
|
||||||
self.root.minsize(1350, 800)
|
self.root.minsize(1350, 800)
|
||||||
|
|
||||||
# Set icon
|
# Set icon
|
||||||
@@ -157,9 +157,9 @@ class MainWindow:
|
|||||||
self.deck_frame = DeckBuilderFrame(self.notebook)
|
self.deck_frame = DeckBuilderFrame(self.notebook)
|
||||||
self.notebook.add(self.deck_frame, text=" 🎴 Deck Builder ")
|
self.notebook.add(self.deck_frame, text=" 🎴 Deck Builder ")
|
||||||
|
|
||||||
# Hints & Skills Tab
|
# Skill Search Tab (Replaces Hints & Skills)
|
||||||
self.hints_frame = HintsSkillsFrame(self.notebook)
|
self.hints_frame = SkillSearchFrame(self.notebook)
|
||||||
self.notebook.add(self.hints_frame, text=" 💡 Hints & Skills ")
|
self.notebook.add(self.hints_frame, text=" 🔍 Skill Search ")
|
||||||
|
|
||||||
def create_status_bar(self, parent):
|
def create_status_bar(self, parent):
|
||||||
"""Create status bar at bottom"""
|
"""Create status bar at bottom"""
|
||||||
|
|||||||
Reference in New Issue
Block a user