mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-26 04:21:07 +01:00
Started on GUI and seperating code so GUI and CLI can share it
This commit is contained in:
parent
e04f4d3b2a
commit
2904e3119f
4 changed files with 262 additions and 42 deletions
|
@ -15,6 +15,7 @@ from collections import Counter
|
||||||
from libtextureconverter.utils import detect_pixel_size, target_dir, colorize, colorize_alpha, handle_default_minecraft_texture, find_all_minecraft_resourcepacks
|
from libtextureconverter.utils import detect_pixel_size, target_dir, colorize, colorize_alpha, handle_default_minecraft_texture, find_all_minecraft_resourcepacks
|
||||||
from libtextureconverter.convert import convert_textures
|
from libtextureconverter.convert import convert_textures
|
||||||
from libtextureconverter.config import SUPPORTED_MINECRAFT_VERSION, working_dir, mineclone2_path, appname, home
|
from libtextureconverter.config import SUPPORTED_MINECRAFT_VERSION, working_dir, mineclone2_path, appname, home
|
||||||
|
from libtextureconverter.gui import main as launch_gui
|
||||||
|
|
||||||
# Argument parsing
|
# Argument parsing
|
||||||
description_text = f"""This is the official MineClone 2 Texture Converter.
|
description_text = f"""This is the official MineClone 2 Texture Converter.
|
||||||
|
@ -45,60 +46,65 @@ verbose = args.verbose
|
||||||
# If False, textures will be put into MineClone 2 directories.
|
# If False, textures will be put into MineClone 2 directories.
|
||||||
make_texture_pack = True # Adjust as needed
|
make_texture_pack = True # Adjust as needed
|
||||||
|
|
||||||
if args.default:
|
if __name__ == "__main__":
|
||||||
base_dir = handle_default_minecraft_texture(home, output_dir)
|
if len(sys.argv) == 1:
|
||||||
|
# No arguments supplied, launch the GUI
|
||||||
|
launch_gui()
|
||||||
|
else:
|
||||||
|
if args.default:
|
||||||
|
base_dir = handle_default_minecraft_texture(home, output_dir)
|
||||||
|
|
||||||
if base_dir == None and not args.all:
|
if base_dir == None and not args.all:
|
||||||
print(
|
print(
|
||||||
"""ERROR: You didn't tell me the path to the Minecraft resource pack.
|
"""ERROR: You didn't tell me the path to the Minecraft resource pack.
|
||||||
Mind-reading has not been implemented yet.
|
Mind-reading has not been implemented yet.
|
||||||
|
|
||||||
Try this:
|
Try this:
|
||||||
"""+appname+""" -i <path to resource pack>
|
"""+appname+""" -i <path to resource pack>
|
||||||
|
|
||||||
For the full help, use:
|
For the full help, use:
|
||||||
"""+appname+""" -h""")
|
"""+appname+""" -h""")
|
||||||
sys.exit(2);
|
sys.exit(2);
|
||||||
|
|
||||||
### END OF SETTINGS ###
|
### END OF SETTINGS ###
|
||||||
|
|
||||||
|
|
||||||
resource_packs = []
|
resource_packs = []
|
||||||
|
|
||||||
if args.all:
|
if args.all:
|
||||||
for resource_path in find_all_minecraft_resourcepacks():
|
for resource_path in find_all_minecraft_resourcepacks():
|
||||||
resource_packs.append(resource_path)
|
resource_packs.append(resource_path)
|
||||||
|
|
||||||
if make_texture_pack and args.input:
|
if make_texture_pack and args.input:
|
||||||
resource_packs.append(args.input)
|
resource_packs.append(args.input)
|
||||||
|
|
||||||
for base_dir in resource_packs:
|
for base_dir in resource_packs:
|
||||||
tex_dir = base_dir + "/assets/minecraft/textures"
|
tex_dir = base_dir + "/assets/minecraft/textures"
|
||||||
|
|
||||||
# Get texture pack name (from directory name)
|
# Get texture pack name (from directory name)
|
||||||
bdir_split = base_dir.split("/")
|
bdir_split = base_dir.split("/")
|
||||||
output_dir_name = bdir_split[-1]
|
output_dir_name = bdir_split[-1]
|
||||||
if len(output_dir_name) == 0:
|
if len(output_dir_name) == 0:
|
||||||
if len(bdir_split) >= 2:
|
if len(bdir_split) >= 2:
|
||||||
output_dir_name = base_dir.split("/")[-2]
|
output_dir_name = base_dir.split("/")[-2]
|
||||||
else:
|
else:
|
||||||
# Fallback
|
# Fallback
|
||||||
output_dir_name = "New_MineClone_2_Texture_Pack"
|
output_dir_name = "New_MineClone_2_Texture_Pack"
|
||||||
|
|
||||||
# ENTRY POINT
|
# ENTRY POINT
|
||||||
if make_texture_pack and not os.path.isdir(output_dir+"/"+output_dir_name):
|
if make_texture_pack and not os.path.isdir(output_dir+"/"+output_dir_name):
|
||||||
os.mkdir(output_dir+"/"+output_dir_name)
|
os.mkdir(output_dir+"/"+output_dir_name)
|
||||||
|
|
||||||
# If, set to convert all resourcepacks, then autodetect pixel size
|
# If, set to convert all resourcepacks, then autodetect pixel size
|
||||||
if args.all:
|
if args.all:
|
||||||
PXSIZE = None
|
PXSIZE = None
|
||||||
|
|
||||||
if PXSIZE is None:
|
if PXSIZE is None:
|
||||||
PXSIZE = detect_pixel_size(base_dir)
|
PXSIZE = detect_pixel_size(base_dir)
|
||||||
tempfile1 = tempfile.NamedTemporaryFile()
|
tempfile1 = tempfile.NamedTemporaryFile()
|
||||||
tempfile2 = tempfile.NamedTemporaryFile()
|
tempfile2 = tempfile.NamedTemporaryFile()
|
||||||
|
|
||||||
convert_textures(make_texture_pack, dry_run, verbose, base_dir, tex_dir, tempfile1, tempfile2, output_dir, output_dir_name, mineclone2_path, PXSIZE)
|
convert_textures(make_texture_pack, dry_run, verbose, base_dir, tex_dir, tempfile1, tempfile2, output_dir, output_dir_name, mineclone2_path, PXSIZE)
|
||||||
|
|
||||||
tempfile1.close()
|
tempfile1.close()
|
||||||
tempfile2.close()
|
tempfile2.close()
|
||||||
|
|
0
tools/libtextureconverter/cli.py
Normal file
0
tools/libtextureconverter/cli.py
Normal file
50
tools/libtextureconverter/common.py
Normal file
50
tools/libtextureconverter/common.py
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import shutil, csv, os, tempfile, sys, argparse, glob
|
||||||
|
from PIL import Image
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
|
from libtextureconverter.utils import detect_pixel_size, target_dir, colorize, colorize_alpha, handle_default_minecraft_texture, find_all_minecraft_resourcepacks
|
||||||
|
from libtextureconverter.convert import convert_textures
|
||||||
|
from libtextureconverter.config import SUPPORTED_MINECRAFT_VERSION, working_dir, mineclone2_path, appname, home
|
||||||
|
from libtextureconverter.gui import main as launch_gui
|
||||||
|
|
||||||
|
def convert_resource_packs(resource_packs, output_dir, PXSIZE):
|
||||||
|
for base_dir in resource_packs:
|
||||||
|
print(f"Converting resource pack: {base_dir}")
|
||||||
|
|
||||||
|
# Autodetect pixel size if not provided
|
||||||
|
if not PXSIZE:
|
||||||
|
pixel_size = detect_pixel_size(base_dir)
|
||||||
|
else:
|
||||||
|
pixel_size = PXSIZE
|
||||||
|
# Construct the path to the textures within the resource pack
|
||||||
|
tex_dir = os.path.join(base_dir, "assets", "minecraft", "textures")
|
||||||
|
|
||||||
|
# Determine the name of the output directory for the converted texture pack
|
||||||
|
output_dir_name = os.path.basename(os.path.normpath(base_dir))
|
||||||
|
|
||||||
|
# Create the output directory if it doesn't exist
|
||||||
|
output_path = os.path.join(output_dir, output_dir_name)
|
||||||
|
if not os.path.isdir(output_path):
|
||||||
|
os.makedirs(output_path, exist_ok=True)
|
||||||
|
|
||||||
|
# Temporary files for conversion (if needed by your conversion process)
|
||||||
|
tempfile1 = tempfile.NamedTemporaryFile(delete=False)
|
||||||
|
tempfile2 = tempfile.NamedTemporaryFile(delete=False)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Perform the actual conversion
|
||||||
|
convert_textures(
|
||||||
|
base_dir=base_dir,
|
||||||
|
tex_dir=tex_dir,
|
||||||
|
temp_files=(tempfile1.name, tempfile2.name),
|
||||||
|
output_dir=output_path,
|
||||||
|
pixel_size=pixel_size
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
# Clean up temporary files
|
||||||
|
tempfile1.close()
|
||||||
|
os.unlink(tempfile1.name)
|
||||||
|
tempfile2.close()
|
||||||
|
os.unlink(tempfile2.name)
|
||||||
|
|
||||||
|
print(f"Finished converting resource pack: {base_dir}")
|
164
tools/libtextureconverter/gui.py
Normal file
164
tools/libtextureconverter/gui.py
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
import tkinter as tk
|
||||||
|
from tkinter import filedialog, messagebox, ttk, font
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
|
||||||
|
class TextureConverterGUI:
|
||||||
|
def __init__(self, root):
|
||||||
|
self.root = root
|
||||||
|
self.root.title("Choose resource packs to convert")
|
||||||
|
|
||||||
|
self.create_widgets()
|
||||||
|
|
||||||
|
def create_widgets(self):
|
||||||
|
|
||||||
|
# Frame for instructions
|
||||||
|
self.instruction_frame = tk.Frame(self.root)
|
||||||
|
self.instruction_frame.pack(fill='x', padx=10, pady=10)
|
||||||
|
tk.Label(self.instruction_frame, text="Do you want to convert installed resource packs, or convert a single zip file?").pack(side='left', fill='x', expand=True)
|
||||||
|
|
||||||
|
# Table-like structure using Treeview
|
||||||
|
self.tree = ttk.Treeview(self.root, columns=('Convert', 'Description'), show='headings')
|
||||||
|
self.tree.heading('Convert', text='Convert')
|
||||||
|
self.tree.heading('Description', text='Description')
|
||||||
|
|
||||||
|
# Inserting options into the table
|
||||||
|
entries = [
|
||||||
|
('all', 'Find Minecraft resource packs installed in your minecraft folders and convert those automatically'),
|
||||||
|
('default', 'Convert the default resource pack'),
|
||||||
|
('other', 'Choose a file to convert manually')
|
||||||
|
]
|
||||||
|
|
||||||
|
for entry in entries:
|
||||||
|
self.tree.insert('', 'end', values=entry)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Button Frame
|
||||||
|
self.button_frame = tk.Frame(self.root)
|
||||||
|
self.button_frame.pack(fill='x', padx=10, pady=10, side='bottom') # Ensure the buttons are at the bottom
|
||||||
|
# Create and pack the buttons separately
|
||||||
|
self.ok_button = tk.Button(self.button_frame, text="OK", command=self.confirm_selection)
|
||||||
|
self.ok_button.pack(side=tk.RIGHT, padx=5)
|
||||||
|
self.cancel_button = tk.Button(self.button_frame, text="Cancel", command=self.cancel_conversion)
|
||||||
|
self.cancel_button.pack(side=tk.RIGHT)
|
||||||
|
|
||||||
|
self.tree.pack(fill='both', expand=True, padx=10, pady=10)
|
||||||
|
|
||||||
|
self.root.after(1, self.adjust_column_widths)
|
||||||
|
|
||||||
|
def adjust_column_widths(self):
|
||||||
|
self.root.update_idletasks() # Update the geometry of the widgets
|
||||||
|
|
||||||
|
# Measure and set the column widths
|
||||||
|
convert_width = tk.font.Font().measure('Convert') + 20
|
||||||
|
description_width = max(
|
||||||
|
tk.font.Font().measure(self.tree.set(item, 'Description')) for item in self.tree.get_children()
|
||||||
|
) + 20
|
||||||
|
|
||||||
|
# Apply the column widths
|
||||||
|
self.tree.column('Convert', width=convert_width, anchor='center')
|
||||||
|
self.tree.column('Description', width=description_width, anchor='w')
|
||||||
|
|
||||||
|
# Calculate the height for each row
|
||||||
|
row_height = tk.font.Font().metrics('linespace') + 2
|
||||||
|
|
||||||
|
# Adjust the Treeview height
|
||||||
|
num_items = len(self.tree.get_children())
|
||||||
|
tree_height = (row_height * num_items) * 1.8
|
||||||
|
self.tree.config(height=num_items)
|
||||||
|
|
||||||
|
# Calculate the total height needed
|
||||||
|
total_height = self.instruction_frame.winfo_height() + self.button_frame.winfo_height() + tree_height + 20
|
||||||
|
|
||||||
|
# Calculate the total width needed
|
||||||
|
total_width = convert_width + description_width + 20
|
||||||
|
|
||||||
|
# Set the size of the window based on content
|
||||||
|
self.root.geometry(f"{int(total_width)}x{int(total_height)}")
|
||||||
|
|
||||||
|
# Prevent the window from resizing smaller than it should
|
||||||
|
self.root.minsize(int(total_width), int(total_height))
|
||||||
|
|
||||||
|
# Update the idle tasks to recalculate sizes, may help to remove extra space
|
||||||
|
self.root.update_idletasks()
|
||||||
|
|
||||||
|
|
||||||
|
def confirm_selection(self):
|
||||||
|
self.cancel_button.config(state=tk.NORMAL)
|
||||||
|
selected_item = self.tree.focus()
|
||||||
|
selection = self.tree.item(selected_item)
|
||||||
|
option = selection['values'][0]
|
||||||
|
self.show_loading_screen(option)
|
||||||
|
|
||||||
|
def set_min_window_size(self):
|
||||||
|
self.root.update_idletasks() # Update the geometry of the widgets
|
||||||
|
self.root.minsize(self.root.winfo_width(), self.root.winfo_height())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def show_loading_screen(self, option):
|
||||||
|
# Display a non-blocking loading message
|
||||||
|
self.loading_label = tk.Label(self.root, text="Converting textures, please wait...", fg="blue")
|
||||||
|
self.loading_label.pack()
|
||||||
|
|
||||||
|
# Start the conversion process in a separate thread
|
||||||
|
conversion_thread = threading.Thread(target=self.perform_conversion, args=(option,), daemon=True)
|
||||||
|
conversion_thread.start()
|
||||||
|
|
||||||
|
# Disable the OK button while the conversion is in progress
|
||||||
|
self.ok_button.config(state=tk.DISABLED)
|
||||||
|
self.cancel_button.config(state=tk.NORMAL)
|
||||||
|
|
||||||
|
def perform_conversion(self, option):
|
||||||
|
# Example names, replace with actual texture pack names after conversion
|
||||||
|
texture_pack_names = ["Texture Pack 1", "Texture Pack 2", "Texture Pack 3"]
|
||||||
|
# Simulate a time-consuming process
|
||||||
|
|
||||||
|
# Perform the selected action
|
||||||
|
if option == 'all':
|
||||||
|
self.convert_all()
|
||||||
|
elif option == 'default':
|
||||||
|
self.convert_default()
|
||||||
|
elif option == 'other':
|
||||||
|
self.open_folder_dialog()
|
||||||
|
|
||||||
|
# Remove the loading message and update the conversion status
|
||||||
|
self.loading_label.pack_forget()
|
||||||
|
messagebox.showinfo("Conversion Complete", f"Resource Packs '{', '.join(texture_pack_names)}' converted.")
|
||||||
|
|
||||||
|
# Re-enable the OK button after the conversion is done
|
||||||
|
self.ok_button.config(state=tk.NORMAL)
|
||||||
|
|
||||||
|
def convert_all(self):
|
||||||
|
# Simulate a conversion process
|
||||||
|
print("Converting all resource packs")
|
||||||
|
time.sleep(2) # Simulate some time for conversion
|
||||||
|
|
||||||
|
def convert_default(self):
|
||||||
|
# Simulate a conversion process
|
||||||
|
print("Converting default resource pack")
|
||||||
|
time.sleep(2) # Simulate some time for conversion
|
||||||
|
|
||||||
|
def open_folder_dialog(self):
|
||||||
|
folder_selected = filedialog.askdirectory()
|
||||||
|
if folder_selected:
|
||||||
|
# Simulate a conversion process
|
||||||
|
print(f"Folder selected for conversion: {folder_selected}")
|
||||||
|
time.sleep(2) # Simulate some time for conversion
|
||||||
|
|
||||||
|
def cancel_conversion(self):
|
||||||
|
# Placeholder for cancel action, you may need to implement actual cancellation logic
|
||||||
|
print("Conversion cancelled by user.")
|
||||||
|
self.loading_label.pack_forget()
|
||||||
|
self.ok_button.config(state=tk.NORMAL)
|
||||||
|
self.cancel_button.config(state=tk.DISABLED)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
root = tk.Tk()
|
||||||
|
app = TextureConverterGUI(root)
|
||||||
|
app.adjust_column_widths()
|
||||||
|
root.mainloop()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in a new issue