Closer to actually editing
This commit is contained in:
@@ -1,28 +1,55 @@
|
|||||||
import math
|
import math
|
||||||
|
import time
|
||||||
from OpenGL.GL import *
|
from OpenGL.GL import *
|
||||||
from OpenGL.GLU import *
|
from OpenGL.GLU import *
|
||||||
from dusk.defs import defs
|
from dusk.defs import defs
|
||||||
|
from editortool.map.map import map
|
||||||
|
|
||||||
pixelsPerUnit = float(defs.get('RPG_CAMERA_PIXELS_PER_UNIT'))
|
class Camera:
|
||||||
yOffset = float(defs.get('RPG_CAMERA_Z_OFFSET'))
|
def __init__(self):
|
||||||
fov = float(defs.get('RPG_CAMERA_FOV'))
|
self.pixelsPerUnit = float(defs.get('RPG_CAMERA_PIXELS_PER_UNIT'))
|
||||||
scale = 8.0
|
self.yOffset = float(defs.get('RPG_CAMERA_Z_OFFSET'))
|
||||||
|
self.fov = float(defs.get('RPG_CAMERA_FOV'))
|
||||||
|
self.scale = 8.0
|
||||||
|
self.lastTime = time.time()
|
||||||
|
self.lookAtTarget = [0.0, 0.0, 0.0]
|
||||||
|
|
||||||
def setupCamera(vw, vh):
|
def setup(self, vw, vh, duration=0.1):
|
||||||
z = (vh / 2.0) / (
|
now = time.time()
|
||||||
(pixelsPerUnit * scale) * math.tan(math.radians(fov / 2.0))
|
delta = now - self.lastTime
|
||||||
)
|
self.lastTime = now
|
||||||
lookAt = ( 0, 0, 0 )
|
# Calculate ease factor for exponential smoothing over 'duration' seconds
|
||||||
aspectRatio = vw / vh
|
ease = 1 - math.exp(-delta / duration)
|
||||||
position = lookAt[0], lookAt[1] - yOffset, lookAt[2] + z
|
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION)
|
z = (vh / 2.0) / (
|
||||||
glLoadIdentity()
|
(self.pixelsPerUnit * self.scale) * math.tan(math.radians(self.fov / 2.0))
|
||||||
gluPerspective(fov, aspectRatio, 0.1, 1000.0)
|
)
|
||||||
glMatrixMode(GL_MODELVIEW)
|
lookAt = [
|
||||||
glLoadIdentity()
|
map.position[0] * float(defs.get('TILE_WIDTH')),
|
||||||
gluLookAt(
|
map.position[1] * float(defs.get('TILE_HEIGHT')),
|
||||||
position[0], position[1], position[2],
|
map.position[2] * float(defs.get('TILE_DEPTH')),
|
||||||
lookAt[0], lookAt[1], lookAt[2],
|
]
|
||||||
0.0, 1.0, 0.0
|
aspectRatio = vw / vh
|
||||||
)
|
|
||||||
|
|
||||||
|
# Ease the lookAt target
|
||||||
|
for i in range(3):
|
||||||
|
self.lookAtTarget[i] += (lookAt[i] - self.lookAtTarget[i]) * ease
|
||||||
|
|
||||||
|
# Camera position is now based on the eased lookAtTarget
|
||||||
|
cameraPosition = (
|
||||||
|
self.lookAtTarget[0],
|
||||||
|
self.lookAtTarget[1] - self.yOffset,
|
||||||
|
self.lookAtTarget[2] + z
|
||||||
|
)
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION)
|
||||||
|
glLoadIdentity()
|
||||||
|
gluPerspective(self.fov, aspectRatio, 0.1, 1000.0)
|
||||||
|
glMatrixMode(GL_MODELVIEW)
|
||||||
|
glLoadIdentity()
|
||||||
|
gluLookAt(
|
||||||
|
cameraPosition[0], cameraPosition[1], cameraPosition[2],
|
||||||
|
self.lookAtTarget[0], self.lookAtTarget[1], self.lookAtTarget[2],
|
||||||
|
0.0, 1.0, 0.0
|
||||||
|
)
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
from editortool.map.chunk import Tile
|
||||||
|
|
||||||
|
class Chunk:
|
||||||
|
def __init__(self, x=0, y=0, z=0, size_x=1, size_y=1, size_z=1):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.z = z
|
||||||
|
self.data = [[[Tile() for _ in range(size_z)] for _ in range(size_y)] for _ in range(size_x)]
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
for x in range(len(self.data)):
|
||||||
|
for y in range(len(self.data[x])):
|
||||||
|
for z in range(len(self.data[x][y])):
|
||||||
|
self.data[x][y][z].draw(x, y, z)
|
||||||
36
tools/editortool/map/chunkpanel.py
Normal file
36
tools/editortool/map/chunkpanel.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, QGridLayout
|
||||||
|
from editortool.map.map import map
|
||||||
|
|
||||||
|
class ChunkPanel(QWidget):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
layout = QVBoxLayout(self)
|
||||||
|
self.chunk_info_label = QLabel("Tile Information")
|
||||||
|
layout.addWidget(self.chunk_info_label)
|
||||||
|
self.move_label = QLabel("Move Selection")
|
||||||
|
layout.addWidget(self.move_label)
|
||||||
|
|
||||||
|
grid = QGridLayout()
|
||||||
|
self.btn_up = QPushButton("U")
|
||||||
|
self.btn_n = QPushButton("N")
|
||||||
|
self.btn_down = QPushButton("D")
|
||||||
|
self.btn_w = QPushButton("W")
|
||||||
|
self.btn_s = QPushButton("S")
|
||||||
|
self.btn_e = QPushButton("E")
|
||||||
|
|
||||||
|
# Arrange buttons: U N D on top row, W S E on bottom row
|
||||||
|
grid.addWidget(self.btn_up, 0, 0)
|
||||||
|
grid.addWidget(self.btn_n, 0, 1)
|
||||||
|
grid.addWidget(self.btn_down, 0, 2)
|
||||||
|
grid.addWidget(self.btn_w, 1, 0)
|
||||||
|
grid.addWidget(self.btn_s, 1, 1)
|
||||||
|
grid.addWidget(self.btn_e, 1, 2)
|
||||||
|
layout.addLayout(grid)
|
||||||
|
layout.addStretch()
|
||||||
|
|
||||||
|
self.btn_n.clicked.connect(lambda: map.moveRelative(0, 1, 0))
|
||||||
|
self.btn_s.clicked.connect(lambda: map.moveRelative(0, -1, 0))
|
||||||
|
self.btn_e.clicked.connect(lambda: map.moveRelative(1, 0, 0))
|
||||||
|
self.btn_w.clicked.connect(lambda: map.moveRelative(-1, 0, 0))
|
||||||
|
self.btn_up.clicked.connect(lambda: map.moveRelative(0, 0, 1))
|
||||||
|
self.btn_down.clicked.connect(lambda: map.moveRelative(0, 0, -1))
|
||||||
@@ -3,8 +3,8 @@ from PyQt5.QtWidgets import QOpenGLWidget
|
|||||||
from OpenGL.GL import *
|
from OpenGL.GL import *
|
||||||
from OpenGL.GLU import *
|
from OpenGL.GLU import *
|
||||||
from editortool.map.selectbox import drawSelectBox
|
from editortool.map.selectbox import drawSelectBox
|
||||||
from editortool.map.tile import drawTile
|
from editortool.map.camera import Camera
|
||||||
from editortool.map.camera import setupCamera
|
from editortool.map.grid import Grid
|
||||||
|
|
||||||
class GLWidget(QOpenGLWidget):
|
class GLWidget(QOpenGLWidget):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
@@ -12,6 +12,8 @@ class GLWidget(QOpenGLWidget):
|
|||||||
self.timer = QTimer(self)
|
self.timer = QTimer(self)
|
||||||
self.timer.timeout.connect(self.update)
|
self.timer.timeout.connect(self.update)
|
||||||
self.timer.start(16) # ~60 FPS
|
self.timer.start(16) # ~60 FPS
|
||||||
|
self.camera = Camera()
|
||||||
|
self.grid = Grid()
|
||||||
|
|
||||||
def initializeGL(self):
|
def initializeGL(self):
|
||||||
glClearColor(0.392, 0.584, 0.929, 1.0)
|
glClearColor(0.392, 0.584, 0.929, 1.0)
|
||||||
@@ -20,7 +22,6 @@ class GLWidget(QOpenGLWidget):
|
|||||||
def resizeGL(self, w, h):
|
def resizeGL(self, w, h):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def paintGL(self):
|
def paintGL(self):
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||||
glLoadIdentity()
|
glLoadIdentity()
|
||||||
@@ -33,8 +34,7 @@ class GLWidget(QOpenGLWidget):
|
|||||||
w = 1
|
w = 1
|
||||||
|
|
||||||
glViewport(0, 0, w, h)
|
glViewport(0, 0, w, h)
|
||||||
setupCamera(self.width(), self.height()) # <-- Add this here
|
self.camera.setup(w, h)
|
||||||
|
|
||||||
# Draw test quad at 0,0,0 to 1,1,0
|
self.grid.draw()
|
||||||
drawTile(0, 0, 0)
|
drawSelectBox()
|
||||||
drawSelectBox(0, 0, 0)
|
|
||||||
46
tools/editortool/map/grid.py
Normal file
46
tools/editortool/map/grid.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
from OpenGL.GL import *
|
||||||
|
from dusk.defs import defs
|
||||||
|
|
||||||
|
class Grid:
|
||||||
|
def __init__(self, lines=1000):
|
||||||
|
self.cellWidth = float(defs.get('TILE_WIDTH'))
|
||||||
|
self.cellHeight = float(defs.get('TILE_HEIGHT'))
|
||||||
|
self.lines = lines
|
||||||
|
self.enabled = True
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
if not self.enabled:
|
||||||
|
return
|
||||||
|
center = [0, 0, 0]
|
||||||
|
halfWidth = self.cellWidth * self.lines // 2
|
||||||
|
halfHeight = self.cellHeight * self.lines // 2
|
||||||
|
# Draw origin axes
|
||||||
|
glBegin(GL_LINES)
|
||||||
|
|
||||||
|
# X axis - RED
|
||||||
|
glColor3f(1.0, 0.0, 0.0)
|
||||||
|
glVertex3f(center[0] - halfWidth, center[1], center[2])
|
||||||
|
glVertex3f(center[0] + halfWidth, center[1], center[2])
|
||||||
|
|
||||||
|
# Y axis - GREEN
|
||||||
|
glColor3f(0.0, 1.0, 0.0)
|
||||||
|
glVertex3f(center[0], center[1] - halfHeight, center[2])
|
||||||
|
glVertex3f(center[0], center[1] + halfHeight, center[2])
|
||||||
|
|
||||||
|
# Z axis - BLUE
|
||||||
|
glColor3f(0.0, 0.0, 1.0)
|
||||||
|
glVertex3f(center[0], center[1], center[2] - halfWidth)
|
||||||
|
glVertex3f(center[0], center[1], center[2] + halfWidth)
|
||||||
|
glEnd()
|
||||||
|
|
||||||
|
# Draw grid
|
||||||
|
glColor3f(0.8, 0.8, 0.8)
|
||||||
|
glBegin(GL_LINES)
|
||||||
|
for i in range(-self.lines // 2, self.lines // 2 + 1):
|
||||||
|
# Vertical lines
|
||||||
|
glVertex3f(center[0] + i * self.cellWidth, center[1] - halfHeight, center[2])
|
||||||
|
glVertex3f(center[0] + i * self.cellWidth, center[1] + halfHeight, center[2])
|
||||||
|
# Horizontal lines
|
||||||
|
glVertex3f(center[0] - halfWidth, center[1] + i * self.cellHeight, center[2])
|
||||||
|
glVertex3f(center[0] + halfWidth, center[1] + i * self.cellHeight, center[2])
|
||||||
|
glEnd()
|
||||||
37
tools/editortool/map/map.py
Normal file
37
tools/editortool/map/map.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
class Map:
|
||||||
|
def __init__(self):
|
||||||
|
self._position = [0, 0, 0] # x, y, z
|
||||||
|
self.listeners = []
|
||||||
|
self.chunks = []
|
||||||
|
self.width = 5
|
||||||
|
self.height = 5
|
||||||
|
self.depth = 3
|
||||||
|
|
||||||
|
@property
|
||||||
|
def position(self):
|
||||||
|
return self._position
|
||||||
|
|
||||||
|
@position.setter
|
||||||
|
def position(self, value):
|
||||||
|
self._position = value
|
||||||
|
self.notifyPositionListeners()
|
||||||
|
|
||||||
|
def addPositionListener(self, listener):
|
||||||
|
self.listeners.append(listener)
|
||||||
|
|
||||||
|
def notifyPositionListeners(self):
|
||||||
|
for listener in self.listeners:
|
||||||
|
listener(self._position)
|
||||||
|
|
||||||
|
def moveTo(self, x, y, z):
|
||||||
|
self.position = [x, y, z]
|
||||||
|
|
||||||
|
def moveRelative(self, x, y, z):
|
||||||
|
self.moveTo(
|
||||||
|
self._position[0] + x,
|
||||||
|
self._position[1] + y,
|
||||||
|
self._position[2] + z
|
||||||
|
)
|
||||||
|
|
||||||
|
# Singleton instance
|
||||||
|
map = Map()
|
||||||
68
tools/editortool/map/mapinfopanel.py
Normal file
68
tools/editortool/map/mapinfopanel.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, QHBoxLayout, QMessageBox
|
||||||
|
from editortool.map.map import map
|
||||||
|
from dusk.defs import defs
|
||||||
|
|
||||||
|
CHUNK_WIDTH = int(defs.get('CHUNK_WIDTH'))
|
||||||
|
CHUNK_HEIGHT = int(defs.get('CHUNK_HEIGHT'))
|
||||||
|
CHUNK_DEPTH = int(defs.get('CHUNK_DEPTH'))
|
||||||
|
|
||||||
|
class MapInfoPanel(QWidget):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
layout = QVBoxLayout()
|
||||||
|
map_info_label = QLabel("Map Information")
|
||||||
|
layout.addWidget(map_info_label)
|
||||||
|
|
||||||
|
map_title_label = QLabel("Map Title")
|
||||||
|
self.map_title_input = QLineEdit()
|
||||||
|
layout.addWidget(map_title_label)
|
||||||
|
layout.addWidget(self.map_title_input)
|
||||||
|
|
||||||
|
tilePositionLabel = QLabel("Tile Position")
|
||||||
|
layout.addWidget(tilePositionLabel)
|
||||||
|
tilePositionRow = QHBoxLayout()
|
||||||
|
self.tileXInput = QLineEdit()
|
||||||
|
self.tileXInput.setPlaceholderText("X")
|
||||||
|
tilePositionRow.addWidget(self.tileXInput)
|
||||||
|
self.tileYInput = QLineEdit()
|
||||||
|
self.tileYInput.setPlaceholderText("Y")
|
||||||
|
tilePositionRow.addWidget(self.tileYInput)
|
||||||
|
self.tileZInput = QLineEdit()
|
||||||
|
self.tileZInput.setPlaceholderText("Z")
|
||||||
|
tilePositionRow.addWidget(self.tileZInput)
|
||||||
|
self.tileGo = QPushButton("Go")
|
||||||
|
tilePositionRow.addWidget(self.tileGo)
|
||||||
|
layout.addLayout(tilePositionRow)
|
||||||
|
|
||||||
|
self.chunkPosLabel = QLabel("Chunk Position: 0, 0, 0")
|
||||||
|
layout.addWidget(self.chunkPosLabel)
|
||||||
|
self.chunkLabel = QLabel("Chunk: 0, 0, 0")
|
||||||
|
layout.addWidget(self.chunkLabel)
|
||||||
|
|
||||||
|
layout.addStretch()
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
self.tileGo.clicked.connect(self.goToPosition)
|
||||||
|
self.tileXInput.returnPressed.connect(self.goToPosition)
|
||||||
|
self.tileYInput.returnPressed.connect(self.goToPosition)
|
||||||
|
self.tileZInput.returnPressed.connect(self.goToPosition)
|
||||||
|
|
||||||
|
self.updatePositionLabels(map.position)
|
||||||
|
map.addPositionListener(self.updatePositionLabels)
|
||||||
|
|
||||||
|
def goToPosition(self):
|
||||||
|
try:
|
||||||
|
x = int(self.tileXInput.text())
|
||||||
|
y = int(self.tileYInput.text())
|
||||||
|
z = int(self.tileZInput.text())
|
||||||
|
map.moveTo(x, y, z)
|
||||||
|
except ValueError:
|
||||||
|
QMessageBox.warning(self, "Invalid Input", "Please enter valid integer coordinates.")
|
||||||
|
|
||||||
|
def updatePositionLabels(self, pos):
|
||||||
|
self.tileXInput.setText(str(pos[0]))
|
||||||
|
self.tileYInput.setText(str(pos[1]))
|
||||||
|
self.tileZInput.setText(str(pos[2]))
|
||||||
|
self.chunkPosLabel.setText(f"Chunk Position: {pos[0] % CHUNK_WIDTH}, {pos[1] % CHUNK_HEIGHT}, {pos[2] % CHUNK_DEPTH}")
|
||||||
|
self.chunkLabel.setText(f"Chunk: {pos[0] // CHUNK_WIDTH}, {pos[1] // CHUNK_HEIGHT}, {pos[2] // CHUNK_DEPTH}")
|
||||||
@@ -1,38 +1,36 @@
|
|||||||
import OpenGL.GL as gl
|
import OpenGL.GL as gl
|
||||||
from dusk.defs import defs
|
from dusk.defs import defs
|
||||||
import colorsys
|
import colorsys
|
||||||
|
from editortool.map.map import map
|
||||||
|
|
||||||
hue = [0.0] # Mutable container for static hue
|
hue = [0.0] # Mutable container for static hue
|
||||||
|
|
||||||
def drawSelectBox(x, y, z):
|
def drawSelectBox():
|
||||||
w = float(defs.get('TILE_WIDTH'))
|
w = float(defs.get('TILE_WIDTH'))
|
||||||
h = float(defs.get('TILE_HEIGHT'))
|
h = float(defs.get('TILE_HEIGHT'))
|
||||||
d = float(defs.get('TILE_DEPTH'))
|
d = float(defs.get('TILE_DEPTH'))
|
||||||
|
position = [
|
||||||
x = x * w
|
map.position[0] * w - (w / 2.0),
|
||||||
y = y * h
|
map.position[1] * h - (h / 2.0),
|
||||||
z = z * d
|
map.position[2] * d - (d / 2.0)
|
||||||
|
]
|
||||||
# Center box.
|
|
||||||
x -= w / 2.0
|
|
||||||
y -= h / 2.0
|
|
||||||
z -= d / 2.0
|
|
||||||
|
|
||||||
# Define the 8 vertices of the cube with w=h=d=1
|
# Define the 8 vertices of the cube with w=h=d=1
|
||||||
vertices = [
|
vertices = [
|
||||||
(x, y, z), # 0: min corner
|
(position[0], position[1], position[2]), # 0: min corner
|
||||||
(x+w, y, z), # 1
|
(position[0]+w, position[1], position[2]), # 1
|
||||||
(x+w, y+h, z), # 2
|
(position[0]+w, position[1]+h, position[2]), # 2
|
||||||
(x, y+h, z), # 3
|
(position[0], position[1]+h, position[2]), # 3
|
||||||
(x, y, z+d), # 4
|
(position[0], position[1], position[2]+d), # 4
|
||||||
(x+w, y, z+d), # 5
|
(position[0]+w, position[1], position[2]+d), # 5
|
||||||
(x+w, y+h, z+d), # 6
|
(position[0]+w, position[1]+h, position[2]+d), # 6
|
||||||
(x, y+h, z+d) # 7
|
(position[0], position[1]+h, position[2]+d) # 7
|
||||||
]
|
]
|
||||||
# List of edges as pairs of vertex indices
|
# List of edges as pairs of vertex indices
|
||||||
edges = [
|
edges = [
|
||||||
(0, 1), (1, 2), (2, 3), (3, 0), # bottom face
|
(0, 1), (1, 2), (2, 3), (3, 0), # bottom face
|
||||||
(4, 5), (5, 6), (6, 7), (7, 4), # top face
|
(4, 5), (5, 6), (6, 7), (7, 4), # top face
|
||||||
|
(4, 5), (5, 6), (6, 7), (7, 4), # top face
|
||||||
(0, 4), (1, 5), (2, 6), (3, 7) # vertical edges
|
(0, 4), (1, 5), (2, 6), (3, 7) # vertical edges
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,29 @@
|
|||||||
from OpenGL.GL import *
|
from OpenGL.GL import *
|
||||||
from dusk.defs import defs
|
from dusk.defs import defs
|
||||||
|
|
||||||
def drawTile(x, y, z):
|
class Tile:
|
||||||
w = float(defs.get('TILE_WIDTH'))
|
def __init__(self):
|
||||||
h = float(defs.get('TILE_HEIGHT'))
|
self.tile_id = 0
|
||||||
d = float(defs.get('TILE_DEPTH'))
|
|
||||||
|
|
||||||
x = x * w
|
def draw(self, x, y, z):
|
||||||
y = y * h
|
w = float(defs.get('TILE_WIDTH'))
|
||||||
z = z * d
|
h = float(defs.get('TILE_HEIGHT'))
|
||||||
|
d = float(defs.get('TILE_DEPTH'))
|
||||||
|
|
||||||
# Center tile.
|
x = x * w
|
||||||
x -= w / 2.0
|
y = y * h
|
||||||
y -= h / 2.0
|
z = z * d
|
||||||
z -= d / 2.0
|
|
||||||
|
|
||||||
# Draw the tile as a flat square on the X-Y plane at depth z.
|
# Center tile.
|
||||||
glColor3f(1.0, 0.0, 0.0) # Red color
|
x -= w / 2.0
|
||||||
glBegin(GL_QUADS)
|
y -= h / 2.0
|
||||||
glVertex3f(x, y, z) # Bottom-left
|
z -= d / 2.0
|
||||||
glVertex3f(x + w, y, z) # Bottom-right
|
|
||||||
glVertex3f(x + w, y + h, z) # Top-right
|
# Draw the tile as a flat square on the X-Y plane at depth z.
|
||||||
glVertex3f(x, y + h, z) # Top-left
|
glColor3f(1.0, 0.0, 0.0) # Red color
|
||||||
glEnd()
|
glBegin(GL_QUADS)
|
||||||
|
glVertex3f(x, y, z) # Bottom-left
|
||||||
|
glVertex3f(x + w, y, z) # Bottom-right
|
||||||
|
glVertex3f(x + w, y + h, z) # Top-right
|
||||||
|
glVertex3f(x, y + h, z) # Top-left
|
||||||
|
glEnd()
|
||||||
@@ -9,6 +9,8 @@ from PyQt5.QtWidgets import (
|
|||||||
QAction, QFileDialog, QLineEdit, QMessageBox
|
QAction, QFileDialog, QLineEdit, QMessageBox
|
||||||
)
|
)
|
||||||
from editortool.map.glwidget import GLWidget
|
from editortool.map.glwidget import GLWidget
|
||||||
|
from editortool.map.chunkpanel import ChunkPanel
|
||||||
|
from editortool.map.mapinfopanel import MapInfoPanel
|
||||||
|
|
||||||
class MapWindow(QMainWindow):
|
class MapWindow(QMainWindow):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -45,41 +47,10 @@ class MapWindow(QMainWindow):
|
|||||||
|
|
||||||
main_layout = QHBoxLayout(central)
|
main_layout = QHBoxLayout(central)
|
||||||
|
|
||||||
# Left panel
|
# Left panel (ChunkPanel)
|
||||||
left_panel = QVBoxLayout()
|
self.chunk_panel = ChunkPanel()
|
||||||
chunk_info_label = QLabel("CHUNK INFO")
|
|
||||||
left_panel.addWidget(chunk_info_label)
|
|
||||||
|
|
||||||
# Movement controls
|
|
||||||
move_label = QLabel("Move Selection")
|
|
||||||
left_panel.addWidget(move_label)
|
|
||||||
btn_n = QPushButton("N")
|
|
||||||
btn_s = QPushButton("S")
|
|
||||||
btn_e = QPushButton("E")
|
|
||||||
btn_w = QPushButton("W")
|
|
||||||
btn_up = QPushButton("Up")
|
|
||||||
btn_down = QPushButton("Down")
|
|
||||||
left_panel.addWidget(btn_n)
|
|
||||||
left_panel.addWidget(btn_s)
|
|
||||||
left_panel.addWidget(btn_e)
|
|
||||||
left_panel.addWidget(btn_w)
|
|
||||||
left_panel.addWidget(btn_up)
|
|
||||||
left_panel.addWidget(btn_down)
|
|
||||||
left_panel.addStretch()
|
|
||||||
|
|
||||||
# Right panel
|
|
||||||
right_panel = QVBoxLayout()
|
|
||||||
map_info_label = QLabel("Map Information")
|
|
||||||
right_panel.addWidget(map_info_label)
|
|
||||||
map_title_label = QLabel("Map Title")
|
|
||||||
self.map_title_input = QLineEdit()
|
|
||||||
right_panel.addWidget(map_title_label)
|
|
||||||
right_panel.addWidget(self.map_title_input)
|
|
||||||
right_panel.addStretch()
|
|
||||||
|
|
||||||
# Add panels to main layout
|
|
||||||
left_widget = QWidget()
|
left_widget = QWidget()
|
||||||
left_widget.setLayout(left_panel)
|
left_widget.setLayout(self.chunk_panel.layout())
|
||||||
left_widget.setFixedWidth(200)
|
left_widget.setFixedWidth(200)
|
||||||
main_layout.addWidget(left_widget)
|
main_layout.addWidget(left_widget)
|
||||||
|
|
||||||
@@ -87,21 +58,15 @@ class MapWindow(QMainWindow):
|
|||||||
self.gl_widget = GLWidget(self)
|
self.gl_widget = GLWidget(self)
|
||||||
main_layout.addWidget(self.gl_widget, stretch=3)
|
main_layout.addWidget(self.gl_widget, stretch=3)
|
||||||
|
|
||||||
right_widget = QWidget()
|
# Right panel (MapInfoPanel)
|
||||||
right_widget.setLayout(right_panel)
|
self.map_info_panel = MapInfoPanel()
|
||||||
|
right_widget = self.map_info_panel
|
||||||
right_widget.setFixedWidth(250)
|
right_widget.setFixedWidth(250)
|
||||||
main_layout.addWidget(right_widget)
|
main_layout.addWidget(right_widget)
|
||||||
|
|
||||||
|
self.map_title_input = self.map_info_panel.map_title_input
|
||||||
self.map_title_input.textChanged.connect(self._on_map_title_changed)
|
self.map_title_input.textChanged.connect(self._on_map_title_changed)
|
||||||
|
|
||||||
# Connect movement buttons
|
|
||||||
btn_n.clicked.connect(lambda: self.move_highlight(0, 1, 0))
|
|
||||||
btn_s.clicked.connect(lambda: self.move_highlight(0, -1, 0))
|
|
||||||
btn_e.clicked.connect(lambda: self.move_highlight(1, 0, 0))
|
|
||||||
btn_w.clicked.connect(lambda: self.move_highlight(-1, 0, 0))
|
|
||||||
btn_up.clicked.connect(lambda: self.move_highlight(0, 0, 1))
|
|
||||||
btn_down.clicked.connect(lambda: self.move_highlight(0, 0, -1))
|
|
||||||
|
|
||||||
def _on_map_title_changed(self):
|
def _on_map_title_changed(self):
|
||||||
self.dirty = True
|
self.dirty = True
|
||||||
|
|
||||||
@@ -109,7 +74,6 @@ class MapWindow(QMainWindow):
|
|||||||
self.current_file = None
|
self.current_file = None
|
||||||
self.map_title_input.setText("")
|
self.map_title_input.setText("")
|
||||||
self.dirty = False
|
self.dirty = False
|
||||||
# ...clear relevant data...
|
|
||||||
|
|
||||||
def openFile(self):
|
def openFile(self):
|
||||||
default_dir = os.path.join(os.path.dirname(__file__), '../../assets/map/')
|
default_dir = os.path.join(os.path.dirname(__file__), '../../assets/map/')
|
||||||
@@ -123,7 +87,7 @@ class MapWindow(QMainWindow):
|
|||||||
self.dirty = False
|
self.dirty = False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.map_title_input.setText("")
|
self.map_title_input.setText("")
|
||||||
# Optionally show error dialog
|
QMessageBox.critical(self, "Error", f"Failed to load file:\n{e}")
|
||||||
|
|
||||||
def saveFile(self):
|
def saveFile(self):
|
||||||
if self.current_file:
|
if self.current_file:
|
||||||
@@ -147,15 +111,7 @@ class MapWindow(QMainWindow):
|
|||||||
json.dump(data, f, indent=2)
|
json.dump(data, f, indent=2)
|
||||||
self.dirty = False
|
self.dirty = False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Optionally show error dialog
|
QMessageBox.critical(self, "Error", f"Failed to save file:\n{e}")
|
||||||
pass
|
|
||||||
|
|
||||||
def move_highlight(self, dx, dy, dz):
|
|
||||||
self.highlighted_pos[0] += dx
|
|
||||||
self.highlighted_pos[1] += dy
|
|
||||||
self.highlighted_pos[2] += dz
|
|
||||||
self.gl_widget.set_highlighted_pos(self.highlighted_pos)
|
|
||||||
self.dirty = True
|
|
||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
if self.dirty:
|
if self.dirty:
|
||||||
|
|||||||
Reference in New Issue
Block a user