import os from PyQt5.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QMessageBox from PyQt5.QtCore import Qt from editortool.map.glwidget import GLWidget from editortool.map.mapleftpanel import MapLeftPanel from editortool.map.mapinfopanel import MapInfoPanel from editortool.map.menubar import MapMenubar from editortool.map.statusbar import StatusBar from dusk.map import Map from dusk.defs import CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH, TILE_SHAPE_NULL, TILE_SHAPE_FLOOR from editortool.map.selectbox import SelectBox from editortool.map.camera import Camera from 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)