Start work on editor
This commit is contained in:
225
tools/editortool/maptool.py
Normal file
225
tools/editortool/maptool.py
Normal file
@@ -0,0 +1,225 @@
|
||||
import sys
|
||||
import os
|
||||
from PyQt5.QtCore import Qt, QTimer
|
||||
from PyQt5.QtWidgets import (
|
||||
QApplication, QMainWindow, QWidget,
|
||||
QHBoxLayout, QVBoxLayout, QPushButton,
|
||||
QLabel, QSlider, QOpenGLWidget, QDialog, QRadioButton, QDialogButtonBox,
|
||||
QAction, QFileDialog, QLineEdit
|
||||
)
|
||||
from OpenGL.GL import *
|
||||
from OpenGL.GLU import *
|
||||
|
||||
class GLWidget(QOpenGLWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.xRot = 20.0
|
||||
self.yRot = 30.0
|
||||
self.zRot = 0.0
|
||||
|
||||
self.rotation_speed = 2.0
|
||||
|
||||
self.timer = QTimer(self)
|
||||
self.timer.timeout.connect(self.updateRotation)
|
||||
|
||||
# ---------- OpenGL lifecycle ----------
|
||||
def initializeGL(self):
|
||||
# Check that context is valid
|
||||
version = glGetString(GL_VERSION)
|
||||
print("GL version:", version)
|
||||
|
||||
glClearColor(0.1, 0.1, 0.1, 1.0)
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
glShadeModel(GL_SMOOTH)
|
||||
|
||||
glEnable(GL_COLOR_MATERIAL)
|
||||
glEnable(GL_LIGHTING)
|
||||
glEnable(GL_LIGHT0)
|
||||
|
||||
light_position = [4.0, 4.0, 8.0, 1.0]
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, light_position)
|
||||
|
||||
def resizeGL(self, w, h):
|
||||
if h == 0:
|
||||
h = 1
|
||||
|
||||
glViewport(0, 0, w, h)
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
glLoadIdentity()
|
||||
glLoadIdentity()
|
||||
gluPerspective(45.0, float(w) / float(h), 0.1, 100.0)
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
|
||||
def paintGL(self):
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||
glLoadIdentity()
|
||||
|
||||
glTranslatef(0.0, 0.0, -7.0)
|
||||
|
||||
glRotatef(self.xRot, 1.0, 0.0, 0.0)
|
||||
glRotatef(self.yRot, 0.0, 1.0, 0.0)
|
||||
glRotatef(self.zRot, 0.0, 0.0, 1.0)
|
||||
|
||||
self.drawCube()
|
||||
|
||||
# ---------- 3D object ----------
|
||||
|
||||
def drawCube(self):
|
||||
glBegin(GL_QUADS)
|
||||
|
||||
# Front (red)
|
||||
glColor3f(1.0, 0.0, 0.0)
|
||||
glVertex3f(-1.0, -1.0, 1.0)
|
||||
glVertex3f( 1.0, -1.0, 1.0)
|
||||
glVertex3f( 1.0, 1.0, 1.0)
|
||||
glVertex3f(-1.0, 1.0, 1.0)
|
||||
|
||||
# Back (green)
|
||||
glColor3f(0.0, 1.0, 0.0)
|
||||
glVertex3f(-1.0, -1.0, -1.0)
|
||||
glVertex3f(-1.0, 1.0, -1.0)
|
||||
glVertex3f( 1.0, 1.0, -1.0)
|
||||
glVertex3f( 1.0, -1.0, -1.0)
|
||||
|
||||
# Top (blue)
|
||||
glColor3f(0.0, 0.0, 1.0)
|
||||
glVertex3f(-1.0, 1.0, -1.0)
|
||||
glVertex3f(-1.0, 1.0, 1.0)
|
||||
glVertex3f( 1.0, 1.0, 1.0)
|
||||
glVertex3f( 1.0, 1.0, -1.0)
|
||||
|
||||
# Bottom (yellow)
|
||||
glColor3f(1.0, 1.0, 0.0)
|
||||
glVertex3f(-1.0, -1.0, -1.0)
|
||||
glVertex3f( 1.0, -1.0, -1.0)
|
||||
glVertex3f( 1.0, -1.0, 1.0)
|
||||
glVertex3f(-1.0, -1.0, 1.0)
|
||||
|
||||
# Right (magenta)
|
||||
glColor3f(1.0, 0.0, 1.0)
|
||||
glVertex3f( 1.0, -1.0, -1.0)
|
||||
glVertex3f( 1.0, 1.0, -1.0)
|
||||
glVertex3f( 1.0, 1.0, 1.0)
|
||||
glVertex3f( 1.0, -1.0, 1.0)
|
||||
|
||||
# Left (cyan)
|
||||
glColor3f(0.0, 1.0, 1.0)
|
||||
glVertex3f(-1.0, -1.0, -1.0)
|
||||
glVertex3f(-1.0, -1.0, 1.0)
|
||||
glVertex3f(-1.0, 1.0, 1.0)
|
||||
glVertex3f(-1.0, 1.0, -1.0)
|
||||
|
||||
glEnd()
|
||||
|
||||
# ---------- Animation control ----------
|
||||
|
||||
def startRotation(self):
|
||||
if not self.timer.isActive():
|
||||
self.timer.start(30) # ms
|
||||
|
||||
def stopRotation(self):
|
||||
if self.timer.isActive():
|
||||
self.timer.stop()
|
||||
|
||||
def resetView(self):
|
||||
self.xRot = 20.0
|
||||
self.yRot = 30.0
|
||||
self.zRot = 0.0
|
||||
self.update()
|
||||
|
||||
def updateRotation(self):
|
||||
self.xRot += self.rotation_speed
|
||||
self.yRot += self.rotation_speed * 0.8
|
||||
self.zRot += self.rotation_speed * 0.5
|
||||
self.update()
|
||||
|
||||
|
||||
class MapWindow(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.setWindowTitle("3D Cube with GUI Buttons (QOpenGLWidget)")
|
||||
self.resize(1280, 720)
|
||||
|
||||
# File menu setup
|
||||
menubar = self.menuBar()
|
||||
file_menu = menubar.addMenu("File")
|
||||
|
||||
action_new = QAction("New", self)
|
||||
action_open = QAction("Open", self)
|
||||
action_save = QAction("Save", self)
|
||||
action_save_as = QAction("Save As", self)
|
||||
|
||||
file_menu.addAction(action_new)
|
||||
file_menu.addAction(action_open)
|
||||
file_menu.addAction(action_save)
|
||||
file_menu.addAction(action_save_as)
|
||||
|
||||
action_new.triggered.connect(self.newFile)
|
||||
action_open.triggered.connect(self.openFile)
|
||||
action_save.triggered.connect(self.saveFile)
|
||||
action_save_as.triggered.connect(self.saveFileAs)
|
||||
|
||||
self.current_file = None
|
||||
|
||||
central = QWidget()
|
||||
self.setCentralWidget(central)
|
||||
|
||||
main_layout = QHBoxLayout(central)
|
||||
|
||||
# Left panel
|
||||
left_panel = QVBoxLayout()
|
||||
chunk_info_label = QLabel("CHUNK INFO")
|
||||
left_panel.addWidget(chunk_info_label)
|
||||
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")
|
||||
map_title_input = QLineEdit()
|
||||
right_panel.addWidget(map_title_label)
|
||||
right_panel.addWidget(map_title_input)
|
||||
right_panel.addStretch()
|
||||
|
||||
# Add panels to main layout
|
||||
left_widget = QWidget()
|
||||
left_widget.setLayout(left_panel)
|
||||
left_widget.setFixedWidth(200)
|
||||
main_layout.addWidget(left_widget)
|
||||
|
||||
# Center panel (GLWidget + controls)
|
||||
self.gl_widget = GLWidget(self)
|
||||
main_layout.addWidget(self.gl_widget, stretch=3)
|
||||
|
||||
right_widget = QWidget()
|
||||
right_widget.setLayout(right_panel)
|
||||
right_widget.setFixedWidth(250)
|
||||
main_layout.addWidget(right_widget)
|
||||
|
||||
def newFile(self):
|
||||
# Implement new file logic here
|
||||
self.current_file = None
|
||||
# ...clear relevant data...
|
||||
|
||||
def openFile(self):
|
||||
default_dir = os.path.join(os.path.dirname(__file__), '../../assets/map/')
|
||||
fname, _ = QFileDialog.getOpenFileName(self, "Open JSON File", default_dir, "JSON Files (*.json)")
|
||||
if fname:
|
||||
self.current_file = fname
|
||||
# ...load file logic...
|
||||
|
||||
def saveFile(self):
|
||||
if self.current_file:
|
||||
# ...save logic...
|
||||
pass
|
||||
else:
|
||||
self.saveFileAs()
|
||||
|
||||
def saveFileAs(self):
|
||||
default_dir = os.path.join(os.path.dirname(__file__), '../../assets/map/')
|
||||
fname, _ = QFileDialog.getSaveFileName(self, "Save JSON File As", default_dir, "JSON Files (*.json)")
|
||||
if fname:
|
||||
self.current_file = fname
|
||||
# ...save logic...
|
||||
Reference in New Issue
Block a user