Addition Of Files
This commit is contained in:
239
gui/main_window.py
Normal file
239
gui/main_window.py
Normal file
@@ -0,0 +1,239 @@
|
||||
"""
|
||||
Main Window for Umamusume Support Card Manager
|
||||
Tabbed interface for card browsing, effects, deck builder, and hints
|
||||
"""
|
||||
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
import sys
|
||||
import os
|
||||
|
||||
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 gui.card_view import CardListFrame
|
||||
from gui.effects_view import EffectsFrame
|
||||
from gui.hints_skills_view import HintsSkillsFrame
|
||||
from gui.deck_builder import DeckBuilderFrame
|
||||
from gui.update_dialog import show_update_dialog
|
||||
from gui.theme import (
|
||||
configure_styles, create_styled_button,
|
||||
BG_DARK, BG_MEDIUM, BG_LIGHT, BG_HIGHLIGHT,
|
||||
ACCENT_PRIMARY, ACCENT_SECONDARY, ACCENT_TERTIARY,
|
||||
TEXT_PRIMARY, TEXT_SECONDARY, TEXT_MUTED,
|
||||
FONT_TITLE, FONT_HEADER, FONT_BODY, FONT_SMALL
|
||||
)
|
||||
from utils import resolve_image_path
|
||||
from version import VERSION
|
||||
|
||||
|
||||
class MainWindow:
|
||||
"""Main application window with tabbed interface"""
|
||||
|
||||
def __init__(self):
|
||||
self.root = tk.Tk()
|
||||
self.root.title("Umamusume Support Card Manager")
|
||||
self.root.geometry("1350x800")
|
||||
self.root.minsize(1350, 800)
|
||||
|
||||
# Set icon
|
||||
try:
|
||||
icon_path = resolve_image_path("1_Special Week.png")
|
||||
if icon_path and os.path.exists(icon_path):
|
||||
icon_img = tk.PhotoImage(file=icon_path)
|
||||
self.root.iconphoto(True, icon_img)
|
||||
except Exception as e:
|
||||
print(f"Failed to set icon: {e}")
|
||||
|
||||
# Configure all styles using centralized theme
|
||||
configure_styles(self.root)
|
||||
|
||||
# Create main container
|
||||
main_container = ttk.Frame(self.root)
|
||||
main_container.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
# Header with stats
|
||||
self.create_header(main_container)
|
||||
|
||||
# Status bar - Create BEFORE notebook to anchor it to bottom
|
||||
self.create_status_bar(main_container)
|
||||
|
||||
# Tabbed notebook
|
||||
self.notebook = ttk.Notebook(main_container)
|
||||
self.notebook.pack(fill=tk.BOTH, expand=True, padx=15, pady=8)
|
||||
|
||||
# Create tabs
|
||||
self.create_tabs()
|
||||
|
||||
def create_header(self, parent):
|
||||
"""Create header with database statistics and update button"""
|
||||
# Header container with subtle bottom border effect
|
||||
header_outer = tk.Frame(parent, bg=BG_DARK)
|
||||
header_outer.pack(fill=tk.X)
|
||||
|
||||
header_frame = tk.Frame(header_outer, bg=BG_DARK)
|
||||
header_frame.pack(fill=tk.X, padx=20, pady=15)
|
||||
|
||||
# Left side: Title and version
|
||||
title_frame = tk.Frame(header_frame, bg=BG_DARK)
|
||||
title_frame.pack(side=tk.LEFT)
|
||||
|
||||
# App icon and title
|
||||
title_label = tk.Label(
|
||||
title_frame,
|
||||
text="🏇 Umamusume Support Card Manager",
|
||||
font=FONT_TITLE,
|
||||
bg=BG_DARK,
|
||||
fg=ACCENT_PRIMARY
|
||||
)
|
||||
title_label.pack(side=tk.LEFT)
|
||||
|
||||
# Version badge
|
||||
version_frame = tk.Frame(title_frame, bg=ACCENT_SECONDARY, padx=8, pady=2)
|
||||
version_frame.pack(side=tk.LEFT, padx=12)
|
||||
version_label = tk.Label(
|
||||
version_frame,
|
||||
text=f"v{VERSION}",
|
||||
font=FONT_SMALL,
|
||||
bg=ACCENT_SECONDARY,
|
||||
fg=TEXT_PRIMARY
|
||||
)
|
||||
version_label.pack()
|
||||
|
||||
# Right side: Update button and stats
|
||||
right_frame = tk.Frame(header_frame, bg=BG_DARK)
|
||||
right_frame.pack(side=tk.RIGHT)
|
||||
|
||||
# Update button with modern styling
|
||||
self.update_button = create_styled_button(
|
||||
right_frame,
|
||||
text="🔄 Check for Updates",
|
||||
command=self.show_update_dialog,
|
||||
style_type='default'
|
||||
)
|
||||
self.update_button.pack(side=tk.RIGHT, padx=(15, 0))
|
||||
|
||||
# Stats panel with card-like appearance
|
||||
stats_frame = tk.Frame(right_frame, bg=BG_MEDIUM, padx=15, pady=8)
|
||||
stats_frame.pack(side=tk.RIGHT)
|
||||
|
||||
stats = get_database_stats()
|
||||
owned = get_owned_count()
|
||||
|
||||
# Build stats text with better formatting
|
||||
stats_parts = [
|
||||
f"📊 {stats.get('total_cards', 0)} Cards",
|
||||
f"✨ {owned} Owned",
|
||||
f"🏆 {stats.get('by_rarity', {}).get('SSR', 0)} SSR",
|
||||
f"⭐ {stats.get('by_rarity', {}).get('SR', 0)} SR",
|
||||
f"● {stats.get('by_rarity', {}).get('R', 0)} R"
|
||||
]
|
||||
stats_text = " │ ".join(stats_parts)
|
||||
|
||||
self.stats_label = tk.Label(
|
||||
stats_frame,
|
||||
text=stats_text,
|
||||
font=FONT_SMALL,
|
||||
bg=BG_MEDIUM,
|
||||
fg=TEXT_SECONDARY
|
||||
)
|
||||
self.stats_label.pack()
|
||||
|
||||
# Subtle separator line
|
||||
separator = tk.Frame(header_outer, bg=BG_LIGHT, height=1)
|
||||
separator.pack(fill=tk.X, padx=15)
|
||||
|
||||
def create_tabs(self):
|
||||
"""Create all tab frames"""
|
||||
# Card List Tab
|
||||
self.card_frame = CardListFrame(self.notebook, on_card_selected_callback=self.on_card_selected)
|
||||
self.notebook.add(self.card_frame, text=" 📋 Card List ")
|
||||
|
||||
# Effects Tab
|
||||
self.effects_frame = EffectsFrame(self.notebook)
|
||||
self.notebook.add(self.effects_frame, text=" 📊 Effects ")
|
||||
|
||||
# Deck Builder Tab
|
||||
self.deck_frame = DeckBuilderFrame(self.notebook)
|
||||
self.notebook.add(self.deck_frame, text=" 🎴 Deck Builder ")
|
||||
|
||||
# Hints & Skills Tab
|
||||
self.hints_frame = HintsSkillsFrame(self.notebook)
|
||||
self.notebook.add(self.hints_frame, text=" 💡 Hints & Skills ")
|
||||
|
||||
def create_status_bar(self, parent):
|
||||
"""Create status bar at bottom"""
|
||||
status_outer = tk.Frame(parent, bg=BG_MEDIUM)
|
||||
status_outer.pack(fill=tk.X, side=tk.BOTTOM)
|
||||
|
||||
status_frame = tk.Frame(status_outer, bg=BG_MEDIUM)
|
||||
status_frame.pack(fill=tk.X, padx=15, pady=8)
|
||||
|
||||
self.status_label = tk.Label(
|
||||
status_frame,
|
||||
text="✓ Ready",
|
||||
font=FONT_SMALL,
|
||||
bg=BG_MEDIUM,
|
||||
fg=TEXT_MUTED
|
||||
)
|
||||
self.status_label.pack(side=tk.LEFT)
|
||||
|
||||
tk.Label(
|
||||
status_frame,
|
||||
text="Data from gametora.com",
|
||||
font=FONT_SMALL,
|
||||
bg=BG_MEDIUM,
|
||||
fg=TEXT_MUTED
|
||||
).pack(side=tk.RIGHT)
|
||||
|
||||
tk.Label(
|
||||
status_frame,
|
||||
text="Made by Kiyreload │ ",
|
||||
font=FONT_SMALL,
|
||||
bg=BG_MEDIUM,
|
||||
fg=ACCENT_TERTIARY
|
||||
).pack(side=tk.RIGHT)
|
||||
|
||||
def on_card_selected(self, card_id, card_name):
|
||||
"""Handle card selection from card list"""
|
||||
# Update other tabs with selected card
|
||||
if hasattr(self, 'effects_frame'):
|
||||
self.effects_frame.set_card(card_id)
|
||||
if hasattr(self, 'hints_frame'):
|
||||
self.hints_frame.set_card(card_id)
|
||||
|
||||
self.status_label.config(text=f"📌 Selected: {card_name}")
|
||||
|
||||
def refresh_stats(self):
|
||||
"""Refresh the statistics display"""
|
||||
stats = get_database_stats()
|
||||
owned = get_owned_count()
|
||||
|
||||
stats_parts = [
|
||||
f"📊 {stats.get('total_cards', 0)} Cards",
|
||||
f"✨ {owned} Owned",
|
||||
f"🏆 {stats.get('by_rarity', {}).get('SSR', 0)} SSR",
|
||||
f"⭐ {stats.get('by_rarity', {}).get('SR', 0)} SR",
|
||||
f"● {stats.get('by_rarity', {}).get('R', 0)} R"
|
||||
]
|
||||
stats_text = " │ ".join(stats_parts)
|
||||
|
||||
self.stats_label.config(text=stats_text)
|
||||
|
||||
def show_update_dialog(self):
|
||||
"""Show the update dialog"""
|
||||
show_update_dialog(self.root)
|
||||
|
||||
def run(self):
|
||||
"""Start the application"""
|
||||
self.root.mainloop()
|
||||
|
||||
|
||||
def main():
|
||||
"""Entry point for GUI"""
|
||||
app = MainWindow()
|
||||
app.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user