Skip to content

Commit c70742f

Browse files
committed
Key bindings and resampling options
1 parent b5870b8 commit c70742f

File tree

3 files changed

+79
-19
lines changed

3 files changed

+79
-19
lines changed

src/autoImport.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,15 +135,20 @@ def autoImport(self):
135135
textureToReplace = Image.open(file)
136136
isSized = isImageSize(textureToReplace, position[2] - position[0], position[3] - position[1])
137137
if not (not isSized and not allowResize):
138-
# Show new texture in preview frame
139-
portviewRes = textureToReplace.resize((256, 256), Image.Resampling.NEAREST)
140-
root.previewFrame.portview.configure(dark_image=portviewRes)
141-
142138
# Replace texture
143139
print("Opening new texture and replacing...")
144140

145141
if not isSized:
146-
textureToReplace = textureToReplace.resize((position[2] - position[0], position[3] - position[1]), Image.Resampling.LANCZOS)
142+
resampling = Image.Resampling.LANCZOS
143+
if self.globalVars.resamplingType == "Bilinear":
144+
resampling = Image.Resampling.BILINEAR
145+
elif self.globalVars.resamplingType == "Nearest":
146+
resampling = Image.Resampling.NEAREST
147+
textureToReplace = textureToReplace.resize((position[2] - position[0], position[3] - position[1]), resampling)
148+
# Show new texture in preview frame
149+
portviewRes = textureToReplace.resize((256, 256), Image.Resampling.NEAREST)
150+
root.previewFrame.portview.configure(dark_image=portviewRes)
151+
# Replace
147152
atlas.addElement(position, textureToReplace)
148153

149154
if not Path(f"{outputDir}/{textureDestDir}").exists():

src/infoDisplay.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,12 @@ def changeTextureFunc(self, value):
104104
messagebox.showerror("Invalid texture", f"Texture selected is not {position[2] - position[0]}x{position[3] - position[1]}")
105105
else:
106106
if not isSized:
107-
textureToReplace = textureToReplace.resize((position[2] - position[0], position[3] - position[1]), Image.Resampling.LANCZOS)
107+
resampling = Image.Resampling.LANCZOS
108+
if self.globalVars.resamplingType == "Bilinear":
109+
resampling = Image.Resampling.BILINEAR
110+
elif self.globalVars.resamplingType == "Nearest":
111+
resampling = Image.Resampling.NEAREST
112+
textureToReplace = textureToReplace.resize((position[2] - position[0], position[3] - position[1]), resampling)
108113
atlas.addElement(position, textureToReplace)
109114
duplicated = checkForMatch(value, added.getItems())
110115

src/main.py

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ def parseConfigFile(fp: str):
4141
config["Preferences"]["showpreviewbg"] = "true"
4242
if not "allowresize" in config["Preferences"]:
4343
config["Preferences"]["allowresize"] = "true"
44+
if not "resampling" in config["Preferences"]:
45+
config["Preferences"]["resampling"] = "Lanczos"
4446

4547
if not config["Preferences"]["theme"] in ("dark", "light"):
4648
config["Preferences"]["theme"] = "dark"
@@ -50,6 +52,9 @@ def parseConfigFile(fp: str):
5052

5153
if not config["Preferences"]["allowresize"] in ("true", "false"):
5254
config["Preferences"]["allowresize"] = "true"
55+
56+
if not config["Preferences"]["resampling"] in ("Bilinear", "Nearest", "Lanczos"):
57+
config["Preferences"]["resampling"] = "Lanczos"
5358
return config
5459

5560
def createNewConfigFile(fp: str | Path, values: dict):
@@ -187,6 +192,7 @@ def __init__(self):
187192
("outputFolder", str),
188193
("showPreviewBg", bool),
189194
("allowResize", bool),
195+
("resamplingType", str),
190196
("items", dict),
191197
("uvs", dict),
192198
("atlasHandler", atlasTexture3dst),
@@ -229,6 +235,7 @@ def __init__(self):
229235
self.globalVars.outputFolder = self.config["Project"]["lastdir"]
230236
self.globalVars.showPreviewBg = self.config["Preferences"]["showpreviewbg"] == "true"
231237
self.globalVars.allowResize = self.config["Preferences"]["allowresize"] == "true"
238+
self.globalVars.resamplingType = self.config["Preferences"]["resampling"]
232239

233240
self.saveChangesForIniFile()
234241
self.changeTheme()
@@ -276,7 +283,7 @@ def __init__(self):
276283
# --------------------------------------------
277284

278285
if self.globalVars.outputFolder != "":
279-
print(self.globalVars.outputFolder)
286+
print("Opening last project:", self.globalVars.outputFolder)
280287
if not Path(self.globalVars.outputFolder).exists():
281288
messagebox.showwarning("Failed to open project", "Last project cannot be opened. Missing directory")
282289
self.globalVars.outputFolder = ""
@@ -294,6 +301,33 @@ def __init__(self):
294301
self.config["Project"]["lastdir"] = ""
295302
self.saveChangesForIniFile()
296303

304+
def key_listener(self, event: tkinter.Event):
305+
key = event.keysym
306+
if key == "Up" or key == "Down":
307+
itemSelected = self.mainFrame.elementsTreeView.selection()
308+
if itemSelected:
309+
items = self.mainFrame.elementsTreeView.get_children()
310+
index = items.index(itemSelected[0])
311+
312+
if key == "Up":
313+
if index > 0:
314+
previous = items[index - 1]
315+
self.mainFrame.elementsTreeView.selection_set(previous)
316+
self.mainFrame.elementsTreeView.focus(previous)
317+
self.mainFrame.elementsTreeView.see(previous)
318+
elif key == "Down":
319+
if index < len(items) - 1:
320+
next_elem = items[index + 1]
321+
self.mainFrame.elementsTreeView.selection_set(next_elem)
322+
self.mainFrame.elementsTreeView.focus(next_elem)
323+
self.mainFrame.elementsTreeView.see(next_elem)
324+
elif key == "Return":
325+
self.mainFrame.searchOptionsFrame.saveSearch()
326+
327+
def click_widget(self, event: tkinter.Event):
328+
if event.widget != self.mainFrame.searchOptionsFrame.entryText._entry:
329+
self.focus()
330+
297331
def saveChangesForIniFile(self):
298332
with open(self.globalVars.runningDir.joinpath("mc3ds-tm.ini"), "w") as configfile:
299333
self.config.write(configfile)
@@ -376,7 +410,7 @@ def openProjectPath():
376410
cancelButton.grid(column=0, row=11, padx=10, pady=15, sticky="e")
377411

378412
applyButton = customtkinter.CTkButton(newProjectWindow, text="Create", command=createProject)
379-
applyButton.grid(column=1, row=11, padx=10, sticky="e", pady=10)
413+
applyButton.grid(column=1, row=11, padx=(0, 10), sticky="e", pady=10)
380414

381415
self.newProjectWindow = newProjectWindow
382416
else:
@@ -466,7 +500,7 @@ def openProject(self, dirpath: str | Path) -> bool:
466500
if isinstance(dirpath, str):
467501
dirpath = Path(dirpath)
468502
if not Path(dirpath).joinpath("project.conf").exists():
469-
messagebox.showerror("Failed to open project", "No project config found in folder")
503+
messagebox.showerror("Failed to open project", "No project config file found in folder")
470504
return False
471505
else:
472506
config = configparser.ConfigParser()
@@ -531,24 +565,35 @@ def openSettings(self):
531565
previewBgCheckbox = customtkinter.CTkCheckBox(settingsWindow, text="Show preview background", variable=previewBgValue, border_width=1, checkbox_width=20, checkbox_height=20)
532566
previewBgCheckbox.grid(column=0, row=3, padx=10, pady=(0, 2), sticky="w")
533567

568+
replaceOpLabel = customtkinter.CTkLabel(settingsWindow, text="Replace options", font=(None, 14, "bold"))
569+
replaceOpLabel.grid(column=0, row=4, padx=10, pady=(10, 0), sticky="ws")
570+
571+
resamplingLabel = customtkinter.CTkLabel(settingsWindow, text="Resampling", font=(None, 12))
572+
resamplingLabel.grid(column=0, row=5, padx=10, pady=0, sticky="ws")
573+
574+
resamplingValue = customtkinter.StringVar(value=self.globalVars.resamplingType)
575+
resamplingCombobox = customtkinter.CTkComboBox(settingsWindow, variable=resamplingValue, values=["Lanczos", "Bilinear", "Nearest"], state="readonly")
576+
resamplingCombobox.grid(column=0, row=6, padx=10, pady=(0, 10), sticky="w")
577+
534578
allowResizeValue = customtkinter.BooleanVar(value=self.globalVars.allowResize)
535579
allowResizeCheckbox = customtkinter.CTkCheckBox(settingsWindow, text="Allow resize textures", variable=allowResizeValue, border_width=1, checkbox_width=20, checkbox_height=20)
536-
allowResizeCheckbox.grid(column=0, row=4, padx=10, pady=(0, 10), sticky="w")
580+
allowResizeCheckbox.grid(column=0, row=7, padx=10, pady=(0, 10), sticky="w")
537581

538582
applyChanges = partial(self.applySettings,
539583
{
540584
"theme": themeValue,
541585
"showpreviewbg": previewBgValue,
542-
"allowresize": allowResizeValue
586+
"allowresize": allowResizeValue,
587+
"resampling": resamplingValue
543588
})
544589

545590
discardChanges = partial(settingsWindow.destroy)
546591

547592
cancelButton = customtkinter.CTkButton(settingsWindow, text="Cancel", command=discardChanges)
548-
cancelButton.grid(column=0, row=5, padx=10, pady=10, sticky="e")
593+
cancelButton.grid(column=0, row=8, padx=10, pady=10, sticky="e")
549594

550595
applyButton = customtkinter.CTkButton(settingsWindow, text="Apply", command=applyChanges)
551-
applyButton.grid(column=1, row=5, padx=(0, 10), pady=10)
596+
applyButton.grid(column=1, row=8, padx=(0, 10), pady=10)
552597

553598
self.settingsWindow = settingsWindow
554599
else:
@@ -559,13 +604,15 @@ def applySettings(self, newSettings: dict):
559604
self.theme = newSettings["theme"].get()
560605
self.globalVars.showPreviewBg = newSettings["showpreviewbg"].get()
561606
self.globalVars.allowResize = newSettings["allowresize"].get()
607+
self.globalVars.resamplingType = newSettings["resampling"].get()
562608

563609
self.changeTheme()
564610
self.mainFrame.infoDispFrame.showItemInfo()
565611

566612
self.config["Preferences"]["theme"] = self.theme
567613
self.config["Preferences"]["showpreviewbg"] = "true" if self.globalVars.showPreviewBg else "false"
568614
self.config["Preferences"]["allowresize"] = "true" if self.globalVars.allowResize else "false"
615+
self.config["Preferences"]["resampling"] = self.globalVars.resamplingType
569616
self.saveChangesForIniFile()
570617

571618
def changeTheme(self):
@@ -580,12 +627,6 @@ def updateListCallback(self):
580627
self.mainFrame.searchOptionsFrame.saveSearch()
581628

582629
def loadResources(self) -> bool:
583-
# Load atlas
584-
if not Path(self.globalVars.outputFolder).joinpath(self.globalVars.atlasPath).exists():
585-
messagebox.showwarning("Missing resource", "The atlas texture cannot be found")
586-
return False
587-
else:
588-
self.globalVars.atlasHandler = atlasTexture3dst().open(Path(self.globalVars.outputFolder).joinpath(self.globalVars.atlasPath), self.globalVars.tilePadding)
589630
# Load uvs and items in atlas
590631
if not Path(self.globalVars.outputFolder).joinpath(self.globalVars.uvsPath).exists():
591632
messagebox.showwarning("Missing resource", "The uvs file cannot be found")
@@ -598,6 +639,12 @@ def loadResources(self) -> bool:
598639
self.globalVars.addedItems = IndexFile().open(os.path.normpath(f"{self.globalVars.outputFolder}/added.txt"))
599640
else:
600641
self.globalVars.addedItems = IndexFile().new()
642+
# Load atlas
643+
if not Path(self.globalVars.outputFolder).joinpath(self.globalVars.atlasPath).exists():
644+
messagebox.showwarning("Missing resource", "The atlas texture cannot be found")
645+
return False
646+
else:
647+
self.globalVars.atlasHandler = atlasTexture3dst().open(Path(self.globalVars.outputFolder).joinpath(self.globalVars.atlasPath), self.globalVars.tilePadding)
601648
return True
602649

603650
def saveChanges(self):
@@ -649,6 +696,9 @@ def updateTreeviewTheme(self):
649696
app.updateTreeviewTheme()
650697
app.bind("<<TreeviewSelect>>", lambda event: app.focus_set())
651698

699+
app.bind("<KeyRelease>", app.key_listener)
700+
app.bind("<Button-1>", app.click_widget)
701+
652702
app.bind('<Alt-F4>', app.closeApp)
653703
app.protocol("WM_DELETE_WINDOW", app.closeApp)
654704

0 commit comments

Comments
 (0)