mirror of
https://github.com/cainan-c/TaikoPythonTools.git
synced 2024-11-23 22:51:02 +01:00
Fix genre colour not working, update gui to look "modern"
This commit is contained in:
parent
997027144e
commit
7fb2ba0cb9
@ -16,6 +16,7 @@ This is still a work in-progress, so please report any issues found to me, along
|
|||||||
Prerequisites:
|
Prerequisites:
|
||||||
Python 3.12.3 or newer
|
Python 3.12.3 or newer
|
||||||
tkinter installed through pip `pip install tk`
|
tkinter installed through pip `pip install tk`
|
||||||
|
sv_ttk installed through pip `pip install sv_ttk`
|
||||||
cryptography installed through pip `pip install cryptography`
|
cryptography installed through pip `pip install cryptography`
|
||||||
pydub installed through pip `pip install pydub`
|
pydub installed through pip `pip install pydub`
|
||||||
ffplay installed in `path`.
|
ffplay installed in `path`.
|
||||||
@ -27,7 +28,7 @@ Due to copyright reasons, etc. no song data will be provided with this tool, how
|
|||||||
Multi-Language Support. (Can be set in config.json, supports en(English) and jp(Japanese)).
|
Multi-Language Support. (Can be set in config.json, supports en(English) and jp(Japanese)).
|
||||||
Custom Song Data loading through the "data_custom" folder. (Path can be changed in config.json).
|
Custom Song Data loading through the "data_custom" folder. (Path can be changed in config.json).
|
||||||
|
|
||||||
![song conversion tool](https://i.imgur.com/zGr0OTb.png)
|
![song conversion tool](https://i.imgur.com/YRXb0NA.png)
|
||||||
|
|
||||||
## Tools Used
|
## Tools Used
|
||||||
at9tool - Used to convert audio to the Sony AT9 format.
|
at9tool - Used to convert audio to the Sony AT9 format.
|
||||||
@ -38,6 +39,7 @@ at9tool - Used to convert audio to the Sony AT9 format.
|
|||||||
Steam User [descatal](https://steamcommunity.com/id/descatal) for writing [this](https://exvsfbce.home.blog/2020/02/04/guide-to-encoding-bnsf-is14-audio-files-converting-wav-back-to-bnsf-is14/) guide on how to create/encode `bnsf` files.
|
Steam User [descatal](https://steamcommunity.com/id/descatal) for writing [this](https://exvsfbce.home.blog/2020/02/04/guide-to-encoding-bnsf-is14-audio-files-converting-wav-back-to-bnsf-is14/) guide on how to create/encode `bnsf` files.
|
||||||
[korenkonder](https://github.com/korenkonder) for compiling the G.722.1 tool used in this project.
|
[korenkonder](https://github.com/korenkonder) for compiling the G.722.1 tool used in this project.
|
||||||
[Kamui/despairoharmony](https://github.com/despairoharmony) for some of the Nijiiro `.nus3bank` template research.
|
[Kamui/despairoharmony](https://github.com/despairoharmony) for some of the Nijiiro `.nus3bank` template research.
|
||||||
|
[rdbende](https://github.com/rdbende) for the [Sun Valley ttk Theme](https://github.com/rdbende/Sun-Valley-ttk-theme) used in this project.
|
||||||
|
|
||||||
## Related Tools
|
## Related Tools
|
||||||
[tja2fumen](https://github.com/vivaria/tja2fumen)
|
[tja2fumen](https://github.com/vivaria/tja2fumen)
|
||||||
|
BIN
TaikoSongConversionTool/gui.ico
Normal file
BIN
TaikoSongConversionTool/gui.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
@ -1,5 +1,6 @@
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk, messagebox
|
from tkinter import ttk, messagebox
|
||||||
|
import sv_ttk
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
@ -69,25 +70,25 @@ if custom_songs == True:
|
|||||||
|
|
||||||
if lang == "jp":
|
if lang == "jp":
|
||||||
genre_map = {
|
genre_map = {
|
||||||
0: ("ポップス", "light blue"),
|
0: ("ポップス", "#219fbb"),
|
||||||
1: ("アニメ", "orange"),
|
1: ("アニメ", "#ff9700"),
|
||||||
2: ("ボーカロイド", "turquoise"),
|
2: ("ボーカロイド", "#a2c4c8"),
|
||||||
3: ("バラエティ", "green"),
|
3: ("バラエティ", "#8fd321"),
|
||||||
4: ("Unused", "gray"),
|
4: ("Unused", "#000000"),
|
||||||
5: ("クラシック", "dark red"),
|
5: ("クラシック", "#d1a016"),
|
||||||
6: ("ゲームミュージック", "purple"),
|
6: ("ゲームミュージック", "#9c72c0"),
|
||||||
7: ("ナムコオリジナル", "dark orange"),
|
7: ("ナムコオリジナル", "#ff5716"),
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
genre_map = {
|
genre_map = {
|
||||||
0: ("POP", "light blue"),
|
0: ("Pop", "#219fbb"),
|
||||||
1: ("Anime", "orange"),
|
1: ("Anime", "#ff9700"),
|
||||||
2: ("Vocaloid", "turquoise"),
|
2: ("Vocaloid", "#a2c4c8"),
|
||||||
3: ("Variety", "green"),
|
3: ("Variety", "#8fd321"),
|
||||||
4: ("Unused", "gray"),
|
4: ("Unused (Kids)", "#000000"),
|
||||||
5: ("Classic", "dark red"),
|
5: ("Classic", "#d1a016"),
|
||||||
6: ("Game Music", "purple"),
|
6: ("Game Music", "#9c72c0"),
|
||||||
7: ("Namco Original", "dark orange"),
|
7: ("Namco Original", "#ff5716"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if lang == "jp":
|
if lang == "jp":
|
||||||
@ -108,15 +109,28 @@ if custom_songs == True:
|
|||||||
window = tk.Tk()
|
window = tk.Tk()
|
||||||
window.title("Taiko no Tatsujin Song Conversion GUI Tool")
|
window.title("Taiko no Tatsujin Song Conversion GUI Tool")
|
||||||
|
|
||||||
|
window.iconbitmap('gui.ico')
|
||||||
|
|
||||||
# Set the initial size of the window
|
# Set the initial size of the window
|
||||||
window.geometry("1000x600") # Width x Height
|
window.geometry("1400x800") # Width x Height
|
||||||
|
|
||||||
|
# Create a new style for Treeview with grid lines
|
||||||
|
style = ttk.Style()
|
||||||
|
style.configure("Treeview", rowheight=25, borderwidth=1)
|
||||||
|
style.layout("Treeview", [('Treeview.treearea', {'sticky': 'nswe'})])
|
||||||
|
|
||||||
|
# Use the new style for the Treeview
|
||||||
|
style.configure("Treeview.Heading", background="lightgrey", foreground="black", borderwidth=1)
|
||||||
|
style.map("Treeview.Heading", background=[('active', 'grey')])
|
||||||
|
|
||||||
|
sv_ttk.set_theme("dark")
|
||||||
|
|
||||||
# Create a frame to contain the Treeview and scrollbar
|
# Create a frame to contain the Treeview and scrollbar
|
||||||
main_frame = ttk.Frame(window)
|
main_frame = ttk.Frame(window)
|
||||||
main_frame.pack(fill="both", expand=True, padx=10, pady=10)
|
main_frame.pack(fill="both", expand=True, padx=10, pady=10)
|
||||||
|
|
||||||
# Create Treeview and Scrollbar
|
# Create Treeview and Scrollbar
|
||||||
tree = ttk.Treeview(main_frame, columns=("Select", "Unique ID", "ID", "Song Name", "Song Subtitle", "Genre", "Difficulty"), show="headings", selectmode="extended")
|
tree = ttk.Treeview(main_frame, columns=("Select", "ID", "Song Name", "Song Subtitle", "Genre", "Difficulty"), show="headings", selectmode="extended")
|
||||||
if lang == "jp":
|
if lang == "jp":
|
||||||
tree.heading("Song Name", text="曲")
|
tree.heading("Song Name", text="曲")
|
||||||
tree.heading("Song Subtitle", text="曲名")
|
tree.heading("Song Subtitle", text="曲名")
|
||||||
@ -129,12 +143,10 @@ else:
|
|||||||
tree.heading("Genre", text="Genre")
|
tree.heading("Genre", text="Genre")
|
||||||
tree.heading("Difficulty", text="Difficulty")
|
tree.heading("Difficulty", text="Difficulty")
|
||||||
tree.heading("Select", text="Select")
|
tree.heading("Select", text="Select")
|
||||||
tree.heading("Unique ID", text="")
|
|
||||||
tree.heading("ID", text="ID")
|
tree.heading("ID", text="ID")
|
||||||
|
|
||||||
|
|
||||||
tree.column("Select", width=50, anchor=tk.CENTER)
|
tree.column("Select", width=50, anchor=tk.CENTER)
|
||||||
tree.column("Unique ID", width=0, anchor=tk.W)
|
|
||||||
tree.column("ID", width=60, anchor=tk.W)
|
tree.column("ID", width=60, anchor=tk.W)
|
||||||
tree.column("Song Name", anchor=tk.W)
|
tree.column("Song Name", anchor=tk.W)
|
||||||
tree.column("Song Subtitle", anchor=tk.W)
|
tree.column("Song Subtitle", anchor=tk.W)
|
||||||
@ -208,23 +220,23 @@ def populate_tree(search_text=""):
|
|||||||
star_ura = song.get("starUra", 0)
|
star_ura = song.get("starUra", 0)
|
||||||
|
|
||||||
difficulty_info_parts = [
|
difficulty_info_parts = [
|
||||||
f"{star_easy}",
|
f"★{star_easy}",
|
||||||
f"{star_normal}",
|
f"★{star_normal}",
|
||||||
f"{star_hard}",
|
f"★{star_hard}",
|
||||||
f"{star_mania}",
|
f"★{star_mania}",
|
||||||
]
|
]
|
||||||
|
|
||||||
if star_ura > 0:
|
if star_ura > 0:
|
||||||
difficulty_info_parts.append(f"{star_ura}")
|
difficulty_info_parts.append(f"★{star_ura}")
|
||||||
|
|
||||||
difficulty_info = " | ".join(difficulty_info_parts)
|
difficulty_info = " | ".join(difficulty_info_parts)
|
||||||
|
|
||||||
# Check if the search text matches the song name
|
# Check if the search text matches the song name
|
||||||
if search_text in english_title.lower():
|
if search_text in english_title.lower():
|
||||||
values = ["☐", "", song_id, english_title, english_subtitle, genre_name, difficulty_info]
|
values = ["☐", song_id, english_title, english_subtitle, genre_name, difficulty_info]
|
||||||
if song_id in selected_song_ids:
|
if song_id in selected_song_ids:
|
||||||
values[0] = "☑"
|
values[0] = "☑"
|
||||||
item_id = tree.insert("", "end", values=values)
|
item_id = tree.insert("", "end", values=values, tags=(genre_name,))
|
||||||
tree.tag_configure(genre_name, background=genre_color)
|
tree.tag_configure(genre_name, background=genre_color)
|
||||||
# Re-select item if it was previously selected
|
# Re-select item if it was previously selected
|
||||||
if song_id in selected_song_ids:
|
if song_id in selected_song_ids:
|
||||||
@ -258,21 +270,21 @@ def sort_tree(sort_option):
|
|||||||
star_ura = song.get("starUra", 0)
|
star_ura = song.get("starUra", 0)
|
||||||
|
|
||||||
difficulty_info_parts = [
|
difficulty_info_parts = [
|
||||||
f"{star_easy}",
|
f"★{star_easy}",
|
||||||
f"{star_normal}",
|
f"★{star_normal}",
|
||||||
f"{star_hard}",
|
f"★{star_hard}",
|
||||||
f"{star_mania}",
|
f"★{star_mania}",
|
||||||
]
|
]
|
||||||
|
|
||||||
if star_ura > 0:
|
if star_ura > 0:
|
||||||
difficulty_info_parts.append(f"{star_ura}")
|
difficulty_info_parts.append(f"★{star_ura}")
|
||||||
|
|
||||||
difficulty_info = " | ".join(difficulty_info_parts)
|
difficulty_info = " | ".join(difficulty_info_parts)
|
||||||
|
|
||||||
values = ["☐", "", song_id, english_title, english_subtitle, genre_name, difficulty_info]
|
values = ["☐", song_id, english_title, english_subtitle, genre_name, difficulty_info]
|
||||||
if song_id in selected_song_ids:
|
if song_id in selected_song_ids:
|
||||||
values[0] = "☑"
|
values[0] = "☑"
|
||||||
item_id = tree.insert("", "end", values=values)
|
item_id = tree.insert("", "end", values=values, tags=(genre_name,))
|
||||||
tree.tag_configure(genre_name, background=genre_color)
|
tree.tag_configure(genre_name, background=genre_color)
|
||||||
# Re-select item if it was previously selected
|
# Re-select item if it was previously selected
|
||||||
if song_id in selected_song_ids:
|
if song_id in selected_song_ids:
|
||||||
@ -300,7 +312,7 @@ def sort_tree(sort_option):
|
|||||||
|
|
||||||
|
|
||||||
def populate_song_entry(song):
|
def populate_song_entry(song):
|
||||||
unique_id = ""
|
#unique_id = ""
|
||||||
song_id = f"{song['id']}"
|
song_id = f"{song['id']}"
|
||||||
genre_no = song["genreNo"]
|
genre_no = song["genreNo"]
|
||||||
genre_name, genre_color = genre_map.get(genre_no, ("Unknown Genre", "white"))
|
genre_name, genre_color = genre_map.get(genre_no, ("Unknown Genre", "white"))
|
||||||
@ -328,7 +340,7 @@ def populate_song_entry(song):
|
|||||||
|
|
||||||
difficulty_info = " | ".join(difficulty_info_parts)
|
difficulty_info = " | ".join(difficulty_info_parts)
|
||||||
|
|
||||||
item_id = tree.insert("", "end", values=("☐", unique_id, song_id, english_title, english_subtitle, genre_name, difficulty_info))
|
tree.insert("", "end", values=("☐", song_id, english_title, english_subtitle, genre_name, difficulty_info))
|
||||||
tree.tag_configure(genre_name, background=genre_color)
|
tree.tag_configure(genre_name, background=genre_color)
|
||||||
|
|
||||||
# Populate the Treeview initially
|
# Populate the Treeview initially
|
||||||
@ -1088,7 +1100,7 @@ preview_button.pack(side="top", padx=20, pady=10)
|
|||||||
|
|
||||||
# Create sorting options
|
# Create sorting options
|
||||||
if lang == "jp":
|
if lang == "jp":
|
||||||
sort_options = ["ID", "曲", "ジャンル順"]
|
sort_options = ["ID", "Song Name", "Genre"]
|
||||||
sort_label = tk.Label(main_frame, text="ソートフィルター:")
|
sort_label = tk.Label(main_frame, text="ソートフィルター:")
|
||||||
else:
|
else:
|
||||||
sort_options = ["ID", "Song Name", "Genre"]
|
sort_options = ["ID", "Song Name", "Genre"]
|
||||||
@ -1097,7 +1109,8 @@ sort_label.pack(side="top", padx=20, pady=5)
|
|||||||
|
|
||||||
sort_var = tk.StringVar(main_frame)
|
sort_var = tk.StringVar(main_frame)
|
||||||
sort_var.set("ID")
|
sort_var.set("ID")
|
||||||
sort_menu = tk.OptionMenu(main_frame, sort_var, *sort_options, command=lambda _: sort_tree(sort_var.get()))
|
sort_menu = ttk.Combobox(main_frame, textvariable=sort_var, values=sort_options)
|
||||||
|
sort_menu.bind("<<ComboboxSelected>>", lambda _: sort_tree(sort_var.get()))
|
||||||
sort_menu.pack(side="top", padx=20, pady=0)
|
sort_menu.pack(side="top", padx=20, pady=0)
|
||||||
|
|
||||||
search_entry.pack(side="top", padx=20, pady=10, fill="x") # search bar, currently broken
|
search_entry.pack(side="top", padx=20, pady=10, fill="x") # search bar, currently broken
|
||||||
@ -1113,10 +1126,11 @@ export_button.pack(side="bottom", padx=20, pady=10)
|
|||||||
selection_count_label = ttk.Label(main_frame, text="0/???")
|
selection_count_label = ttk.Label(main_frame, text="0/???")
|
||||||
selection_count_label.pack(side="bottom", padx=20, pady=10)
|
selection_count_label.pack(side="bottom", padx=20, pady=10)
|
||||||
|
|
||||||
|
# Game platform selection
|
||||||
game_platform_var = tk.StringVar(main_frame)
|
game_platform_var = tk.StringVar(main_frame)
|
||||||
game_platform_var.set("PS4")
|
game_platform_var.set("PS4")
|
||||||
game_platform_choices = ["PS4", "NS1", "PTB"]
|
game_platform_choices = ["PS4", "NS1", "PTB"]
|
||||||
game_platform_menu = tk.OptionMenu(main_frame, game_platform_var, *game_platform_choices)
|
game_platform_menu = ttk.Combobox(main_frame, textvariable=game_platform_var, values=game_platform_choices)
|
||||||
game_platform_menu.pack(side="bottom", padx=20, pady=0)
|
game_platform_menu.pack(side="bottom", padx=20, pady=0)
|
||||||
|
|
||||||
# Create Label for Platform selection
|
# Create Label for Platform selection
|
||||||
@ -1126,19 +1140,21 @@ else:
|
|||||||
platform_label = tk.Label(main_frame, text="Platform")
|
platform_label = tk.Label(main_frame, text="Platform")
|
||||||
platform_label.pack(side="bottom", padx=20, pady=5)
|
platform_label.pack(side="bottom", padx=20, pady=5)
|
||||||
|
|
||||||
# Game region selection, needed for wordlist export.
|
# Game region selection, needed for wordlist export
|
||||||
game_region_var = tk.StringVar(main_frame)
|
game_region_var = tk.StringVar(main_frame)
|
||||||
game_region_var.set("JPN/ASIA")
|
game_region_var.set("JPN/ASIA")
|
||||||
game_region_choices = ["JPN/ASIA", "EU/USA"]
|
game_region_choices = ["JPN/ASIA", "EU/USA"]
|
||||||
game_region_menu = tk.OptionMenu(main_frame, game_region_var, *game_region_choices)
|
game_region_menu = ttk.Combobox(main_frame, textvariable=game_region_var, values=game_region_choices)
|
||||||
game_region_menu.pack(side="bottom", padx=20, pady=10)
|
game_region_menu.pack(side="bottom", padx=20, pady=10)
|
||||||
|
|
||||||
|
# Create Label for Region selection
|
||||||
if lang == "jp":
|
if lang == "jp":
|
||||||
game_region_label = tk.Label(main_frame, text="ゲーム地域:")
|
game_region_label = tk.Label(main_frame, text="ゲーム地域:")
|
||||||
else:
|
else:
|
||||||
game_region_label = tk.Label(main_frame, text="Game Region:")
|
game_region_label = tk.Label(main_frame, text="Game Region:")
|
||||||
game_region_label.pack(side="bottom", padx=20, pady=0)
|
game_region_label.pack(side="bottom", padx=20, pady=0)
|
||||||
|
|
||||||
|
|
||||||
# Doesn't function?
|
# Doesn't function?
|
||||||
# Update selection count when tree selection changes
|
# Update selection count when tree selection changes
|
||||||
#tree.bind("<<TreeviewSelect>>", lambda event: update_selection_count())
|
#tree.bind("<<TreeviewSelect>>", lambda event: update_selection_count())
|
||||||
|
Loading…
Reference in New Issue
Block a user