From 3697cc3eefeec4bf30471221ac3a5b172c674f89 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Thu, 20 Nov 2025 16:45:50 -0600 Subject: [PATCH] Prep ent --- tools/dusk/tile.py | 21 ------ tools/editor.py | 6 +- tools/editortool/cutscene/cutsceneitem.py | 53 +++++++++++++++ tools/editortool/cutscene/cutscenetext.py | 21 ++++++ tools/editortool/cutscene/cutscenewait.py | 20 ++++++ tools/editortool/cutscenetool.py | 80 +++++++++++++++++++++++ tools/editortool/maptool.py | 10 ++- 7 files changed, 185 insertions(+), 26 deletions(-) create mode 100644 tools/editortool/cutscene/cutsceneitem.py create mode 100644 tools/editortool/cutscene/cutscenetext.py create mode 100644 tools/editortool/cutscene/cutscenewait.py create mode 100644 tools/editortool/cutscenetool.py diff --git a/tools/dusk/tile.py b/tools/dusk/tile.py index 6051d73..85f94d8 100644 --- a/tools/dusk/tile.py +++ b/tools/dusk/tile.py @@ -177,27 +177,6 @@ class Tile: def buffer(self, vertexBuffer): if self.shape == TILE_SHAPE_NULL: return - # Old code: - # if self.x != 0 or self.y != 0 or self.z != 0: - # return # Only buffer the tile at (0,0,0) - # Center tile. - # x = self.posX - TILE_WIDTH / 2.0 - # y = self.posY - TILE_HEIGHT / 2.0 - # z = self.posZ - TILE_DEPTH / 2.0 - # w = TILE_WIDTH - # h = TILE_HEIGHT - # d = TILE_DEPTH - - # # Quad on the XY plane at z - # vertexBuffer.vertices.extend([ - # x, y, z, # bottom left - # x + w, y, z, # bottom right - # x + w, y + h, z, # top right - - # x, y, z, # bottom left - # x + w, y + h, z, # top right - # x, y + h, z # top left - # ]) # New code: baseData = self.getBaseTileModel() diff --git a/tools/editor.py b/tools/editor.py index 196cf4d..fa36166 100755 --- a/tools/editor.py +++ b/tools/editor.py @@ -8,13 +8,15 @@ from OpenGL.GL import * from OpenGL.GLU import * from editortool.maptool import MapWindow from editortool.langtool import LangToolWindow +from editortool.cutscenetool import CutsceneToolWindow -# DEFAULT_TOOL = None +DEFAULT_TOOL = None DEFAULT_TOOL = "map" TOOLS = [ ("Map Editor", "map", MapWindow), - ("Language Editor", "language", LangToolWindow) + ("Language Editor", "language", LangToolWindow), + ("Cutscene Editor", "cutscene", CutsceneToolWindow), ] class EditorChoiceDialog(QDialog): diff --git a/tools/editortool/cutscene/cutsceneitem.py b/tools/editortool/cutscene/cutsceneitem.py new file mode 100644 index 0000000..4ccf082 --- /dev/null +++ b/tools/editortool/cutscene/cutsceneitem.py @@ -0,0 +1,53 @@ +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLineEdit, QLabel, QSizePolicy, QComboBox, QHBoxLayout, QSpacerItem +from PyQt5.QtCore import Qt, pyqtSignal +from .cutscenewait import CutsceneWaitEditor +from .cutscenetext import CutsceneTextEditor + +EDITOR_MAP = ( + ( "wait", "Wait", CutsceneWaitEditor ), + ( "text", "Text", CutsceneTextEditor ) +) + +class CutsceneItemEditor(QWidget): + def __init__(self, parent=None): + super().__init__(parent) + self.layout = QVBoxLayout(self) + self.layout.setAlignment(Qt.AlignTop | Qt.AlignLeft) + self.layout.addWidget(QLabel("Item Properties:")) + + rowLayout = QHBoxLayout() + rowLayout.setSpacing(8) + + rowLayout.addWidget(QLabel("Name:")) + self.nameInput = QLineEdit() + rowLayout.addWidget(self.nameInput) + + rowLayout.addWidget(QLabel("Type:")) + self.typeDropdown = QComboBox() + self.typeDropdown.addItems([typeName for typeKey, typeName, editorClass in EDITOR_MAP]) + rowLayout.addWidget(self.typeDropdown) + self.layout.addLayout(rowLayout) + + self.activeEditor = None + + # Events + self.typeDropdown.currentTextChanged.connect(self.onTypeChanged) + + # First load + self.onTypeChanged(self.typeDropdown.currentText()) + + def onTypeChanged(self, typeText): + typeKey = typeText.lower() + + # Remove existing editor + if self.activeEditor: + self.layout.removeWidget(self.activeEditor) + self.activeEditor.deleteLater() + self.activeEditor = None + + # Create new editor + for key, name, editorClass in EDITOR_MAP: + if key == typeKey: + self.activeEditor = editorClass() + self.layout.addWidget(self.activeEditor) + break \ No newline at end of file diff --git a/tools/editortool/cutscene/cutscenetext.py b/tools/editortool/cutscene/cutscenetext.py new file mode 100644 index 0000000..bf963dd --- /dev/null +++ b/tools/editortool/cutscene/cutscenetext.py @@ -0,0 +1,21 @@ +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QTextEdit +from PyQt5.QtCore import Qt + +class CutsceneTextEditor(QWidget): + def __init__(self, parent=None): + super().__init__(parent) + layout = QVBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(0) + label = QLabel("Text:") + label.setSizePolicy(label.sizePolicy().Expanding, label.sizePolicy().Fixed) + layout.addWidget(label) + self.textInput = QTextEdit() + self.textInput.setSizePolicy(self.textInput.sizePolicy().Expanding, self.textInput.sizePolicy().Expanding) + layout.addWidget(self.textInput, stretch=1) + + def setText(self, text): + self.textInput.setPlainText(text) + + def getText(self): + return self.textInput.toPlainText() diff --git a/tools/editortool/cutscene/cutscenewait.py b/tools/editortool/cutscene/cutscenewait.py new file mode 100644 index 0000000..3dffb9c --- /dev/null +++ b/tools/editortool/cutscene/cutscenewait.py @@ -0,0 +1,20 @@ +from PyQt5.QtWidgets import QWidget, QFormLayout, QDoubleSpinBox, QLabel + +class CutsceneWaitEditor(QWidget): + def __init__(self, parent=None): + super().__init__(parent) + layout = QFormLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(0) + self.waitTimeInput = QDoubleSpinBox() + self.waitTimeInput.setMinimum(0.0) + self.waitTimeInput.setMaximum(9999.0) + self.waitTimeInput.setDecimals(2) + self.waitTimeInput.setSingleStep(0.1) + layout.addRow(QLabel("Wait Time (seconds):"), self.waitTimeInput) + + def setWaitTime(self, value): + self.waitTimeInput.setValue(value) + + def getWaitTime(self): + return self.waitTimeInput.value() diff --git a/tools/editortool/cutscenetool.py b/tools/editortool/cutscenetool.py new file mode 100644 index 0000000..e9f88ab --- /dev/null +++ b/tools/editortool/cutscenetool.py @@ -0,0 +1,80 @@ +from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QListWidget, QListWidgetItem +from editortool.cutscene.cutsceneitem import CutsceneItemEditor +import sys + +class CutsceneToolWindow(QMainWindow): + def __init__(self): + super().__init__() + self.setWindowTitle("Dusk Cutscene Editor") + self.setGeometry(100, 100, 800, 600) + self.nextItemNumber = 1 # Track next available number + + # Main layout: horizontal split + central = QWidget() + mainLayout = QHBoxLayout(central) + self.setCentralWidget(central) + + # Timeline + leftPanel = QWidget() + leftLayout = QVBoxLayout(leftPanel) + + self.timelineList = QListWidget() + self.timelineList.setSelectionMode(QListWidget.SingleSelection) + leftLayout.addWidget(QLabel("Cutscene Timeline")) + leftLayout.addWidget(self.timelineList) + + btnLayout = QHBoxLayout() + self.addBtn = QPushButton("Add") + self.removeBtn = QPushButton("Remove") + btnLayout.addWidget(self.addBtn) + btnLayout.addWidget(self.removeBtn) + leftLayout.addLayout(btnLayout) + mainLayout.addWidget(leftPanel, 2) + + # Property editor + self.editorPanel = QWidget() + self.editorLayout = QVBoxLayout(self.editorPanel) + self.itemEditor = None # Only create when needed + mainLayout.addWidget(self.editorPanel, 3) + + # Events + self.timelineList.currentItemChanged.connect(self.onItemSelected) + self.addBtn.clicked.connect(self.addCutsceneItem) + self.removeBtn.clicked.connect(self.removeCutsceneItem) + + def addCutsceneItem(self): + name = f"Cutscene item {self.nextItemNumber}" + item = QListWidgetItem(name) + self.timelineList.addItem(item) + self.timelineList.setCurrentItem(item) + self.nextItemNumber += 1 + + def removeCutsceneItem(self): + row = self.timelineList.currentRow() + if row >= 0: + self.timelineList.takeItem(row) + # Remove editor if nothing selected + if self.timelineList.currentItem() is None: + if self.itemEditor: + self.editorLayout.removeWidget(self.itemEditor) + self.itemEditor.deleteLater() + self.itemEditor = None + + def onItemSelected(self, current, previous): + if current: + if not self.itemEditor: + self.itemEditor = CutsceneItemEditor() + self.editorLayout.addWidget(self.itemEditor) + return + + if not self.itemEditor: + return + self.editorLayout.removeWidget(self.itemEditor) + self.itemEditor.deleteLater() + self.itemEditor = None + +if __name__ == "__main__": + app = QApplication(sys.argv) + window = CutsceneToolWindow() + window.show() + sys.exit(app.exec_()) diff --git a/tools/editortool/maptool.py b/tools/editortool/maptool.py index 7a6e6aa..4bfdd99 100644 --- a/tools/editortool/maptool.py +++ b/tools/editortool/maptool.py @@ -1,5 +1,5 @@ import os -from PyQt5.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QMessageBox +from PyQt5.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QMessageBox, QTabWidget from PyQt5.QtCore import Qt from editortool.map.glwidget import GLWidget from editortool.map.chunkpanel import ChunkPanel @@ -36,10 +36,14 @@ class MapWindow(QMainWindow): self.setCentralWidget(central) mainLayout = QHBoxLayout(central) - # Left panel (ChunkPanel) + # Tabs (left) + self.tabs = QTabWidget() + self.chunkPanel = ChunkPanel(self) self.chunkPanel.setFixedWidth(200) - mainLayout.addWidget(self.chunkPanel) + self.tabs.addTab(self.chunkPanel, "Tile Editor") + + mainLayout.addWidget(self.tabs) # Center panel (GLWidget + controls) self.glWidget = GLWidget(self)