import os from PyQt5.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QMessageBox from PyQt5.QtCore import Qt from tools.editortool.map.glwidget import GLWidget from tools.editortool.map.mapleftpanel import MapLeftPanel from tools.editortool.map.mapinfopanel import MapInfoPanel from tools.editortool.map.menubar import MapMenubar from tools.editortool.map.statusbar import StatusBar from tools.dusk.map import Map from tools.dusk.defs import CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH, TILE_SHAPE_NULL, TILE_SHAPE_FLOOR from tools.editortool.map.selectbox import SelectBox from tools.editortool.map.camera import Camera from tools.editortool.map.grid import Grid class MapWindow(QMainWindow): def __init__(self): super().__init__() self.insertPressed = False self.deletePressed = False # Subclasses self.map = Map(self) self.camera = Camera(self) self.grid = Grid() self.selectBox = SelectBox(self) # Window setup self.setWindowTitle("Dusk Map Editor") self.resize(1600, 900) # Menubar (TESTING) self.menubar = MapMenubar(self) central = QWidget() self.setCentralWidget(central) mainLayout = QHBoxLayout(central) # Left panel (tabs + nav buttons) self.leftPanel = MapLeftPanel(self) self.leftPanel.setFixedWidth(350) mainLayout.addWidget(self.leftPanel) # Center panel (GLWidget + controls) self.glWidget = GLWidget(self) mainLayout.addWidget(self.glWidget, stretch=3) # Right panel (MapInfoPanel) self.mapInfoPanel = MapInfoPanel(self) rightWidget = self.mapInfoPanel rightWidget.setFixedWidth(250) mainLayout.addWidget(rightWidget) # Status bar self.statusBar = StatusBar(self) self.setStatusBar(self.statusBar) self.installEventFilter(self) self.installEventFilterRecursively(self) def installEventFilterRecursively(self, widget): for child in widget.findChildren(QWidget): child.installEventFilter(self) self.installEventFilterRecursively(child) def closeEvent(self, event): if not self.map.isDirty(): event.accept() return reply = QMessageBox.question( self, "Unsaved Changes", "You have unsaved changes. Do you want to save before closing?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel, QMessageBox.Save ) if reply == QMessageBox.Save: self.map.save() elif reply == QMessageBox.Cancel: event.ignore() return event.accept() def eventFilter(self, obj, event): if event.type() == event.KeyPress: amtX, amtY, amtZ = 0, 0, 0 key = event.key() if key == Qt.Key_Left: amtX = -1 elif key == Qt.Key_Right: amtX = 1 elif key == Qt.Key_Up: amtY = -1 elif key == Qt.Key_Down: amtY = 1 elif key == Qt.Key_PageUp: amtZ = 1 elif key == Qt.Key_PageDown: amtZ = -1 if event.modifiers() & Qt.ShiftModifier: amtX *= CHUNK_WIDTH amtY *= CHUNK_HEIGHT amtZ *= CHUNK_DEPTH if amtX != 0 or amtY != 0 or amtZ != 0: self.map.moveRelative(amtX, amtY, amtZ) if self.insertPressed: tile = self.map.getTileAtWorldPos(*self.map.position) if tile is not None and tile.shape == TILE_SHAPE_NULL: tile.setShape(TILE_SHAPE_FLOOR) if self.deletePressed: tile = self.map.getTileAtWorldPos(*self.map.position) if tile is not None: tile.setShape(TILE_SHAPE_NULL) event.accept() return True if key == Qt.Key_Delete: tile = self.map.getTileAtWorldPos(*self.map.position) self.deletePressed = True if tile is not None: tile.setShape(TILE_SHAPE_NULL) event.accept() return True if key == Qt.Key_Insert: tile = self.map.getTileAtWorldPos(*self.map.position) self.insertPressed = True if tile is not None and tile.shape == TILE_SHAPE_NULL: tile.setShape(TILE_SHAPE_FLOOR) event.accept() elif event.type() == event.KeyRelease: key = event.key() if key == Qt.Key_Delete: self.deletePressed = False event.accept() return True if key == Qt.Key_Insert: self.insertPressed = False event.accept() return super().eventFilter(obj, event)