pyscreeps-arena 0.5.7b0__py3-none-any.whl → 0.5.7.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyscreeps_arena/__init__.py +35 -3
- pyscreeps_arena/core/const.py +1 -1
- pyscreeps_arena/project.7z +0 -0
- pyscreeps_arena/ui/__init__.py +3 -1
- pyscreeps_arena/ui/map_render.py +705 -0
- pyscreeps_arena/ui/mapviewer.py +14 -0
- pyscreeps_arena/ui/qcreeplogic/qcreeplogic.py +82 -21
- pyscreeps_arena/ui/qmapv/__init__.py +3 -0
- pyscreeps_arena/ui/qmapv/qcinfo.py +567 -0
- pyscreeps_arena/ui/qmapv/qco.py +441 -0
- pyscreeps_arena/ui/qmapv/qmapv.py +728 -0
- pyscreeps_arena/ui/qmapv/test_array_drag.py +191 -0
- pyscreeps_arena/ui/qmapv/test_drag.py +107 -0
- pyscreeps_arena/ui/qmapv/test_qcinfo.py +169 -0
- pyscreeps_arena/ui/qmapv/test_qco_drag.py +7 -0
- pyscreeps_arena/ui/qmapv/test_qmapv.py +224 -0
- pyscreeps_arena/ui/qmapv/test_simple_array.py +303 -0
- {pyscreeps_arena-0.5.7b0.dist-info → pyscreeps_arena-0.5.7.2.dist-info}/METADATA +1 -1
- pyscreeps_arena-0.5.7.2.dist-info/RECORD +40 -0
- pyscreeps_arena-0.5.7b0.dist-info/RECORD +0 -28
- {pyscreeps_arena-0.5.7b0.dist-info → pyscreeps_arena-0.5.7.2.dist-info}/WHEEL +0 -0
- {pyscreeps_arena-0.5.7b0.dist-info → pyscreeps_arena-0.5.7.2.dist-info}/entry_points.txt +0 -0
- {pyscreeps_arena-0.5.7b0.dist-info → pyscreeps_arena-0.5.7.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Test script for array format drag and drop functionality
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
import json
|
|
9
|
+
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
|
|
10
|
+
QHBoxLayout, QPushButton, QLabel, QListWidget)
|
|
11
|
+
from PyQt6.QtCore import Qt, QMimeData, pyqtSignal
|
|
12
|
+
from PyQt6.QtGui import QDrag, QPixmap
|
|
13
|
+
|
|
14
|
+
# Add the parent directory to the path to import our modules
|
|
15
|
+
sys.path.insert(0, 'f:\\Python\\Python312\\Lib\\site-packages\\pyscreeps_arena\\ui\\qmapv')
|
|
16
|
+
|
|
17
|
+
from qco import QPSACellObject
|
|
18
|
+
from qcinfo import QPSACellInfo
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class DragSourceWidget(QWidget):
|
|
22
|
+
"""Widget that can initiate drag operations with array format."""
|
|
23
|
+
|
|
24
|
+
def __init__(self, parent=None):
|
|
25
|
+
super().__init__(parent)
|
|
26
|
+
self._init_ui()
|
|
27
|
+
|
|
28
|
+
def _init_ui(self):
|
|
29
|
+
"""Initialize UI."""
|
|
30
|
+
layout = QVBoxLayout()
|
|
31
|
+
|
|
32
|
+
# Create test data
|
|
33
|
+
self.test_array = [
|
|
34
|
+
{
|
|
35
|
+
"x": 10,
|
|
36
|
+
"y": 20,
|
|
37
|
+
"type": "Creep",
|
|
38
|
+
"method": "move",
|
|
39
|
+
"id": "creep1",
|
|
40
|
+
"name": "Worker1"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"x": 15,
|
|
44
|
+
"y": 25,
|
|
45
|
+
"type": "Structure",
|
|
46
|
+
"method": "build",
|
|
47
|
+
"id": "struct1",
|
|
48
|
+
"name": "Spawn1"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"x": 30,
|
|
52
|
+
"y": 40,
|
|
53
|
+
"type": "Resource",
|
|
54
|
+
"method": "harvest",
|
|
55
|
+
"id": "res1",
|
|
56
|
+
"name": "Energy1"
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
self.test_single = {
|
|
61
|
+
"x": 50,
|
|
62
|
+
"y": 60,
|
|
63
|
+
"type": "Tower",
|
|
64
|
+
"method": "attack",
|
|
65
|
+
"id": "tower1",
|
|
66
|
+
"name": "Defense1"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Add buttons to trigger drag operations
|
|
70
|
+
btn_array = QPushButton("Drag Array [{}]")
|
|
71
|
+
btn_array.clicked.connect(lambda: self._start_drag(self.test_array))
|
|
72
|
+
layout.addWidget(btn_array)
|
|
73
|
+
|
|
74
|
+
btn_single = QPushButton("Drag Single {}")
|
|
75
|
+
btn_single.clicked.connect(lambda: self._start_drag(self.test_single))
|
|
76
|
+
layout.addWidget(btn_single)
|
|
77
|
+
|
|
78
|
+
# Add labels to show what will be dragged
|
|
79
|
+
label_array = QLabel(f"Array: {json.dumps(self.test_array, indent=2)}")
|
|
80
|
+
label_array.setWordWrap(True)
|
|
81
|
+
layout.addWidget(label_array)
|
|
82
|
+
|
|
83
|
+
label_single = QLabel(f"Single: {json.dumps(self.test_single, indent=2)}")
|
|
84
|
+
label_single.setWordWrap(True)
|
|
85
|
+
layout.addWidget(label_single)
|
|
86
|
+
|
|
87
|
+
self.setLayout(layout)
|
|
88
|
+
|
|
89
|
+
def _start_drag(self, data):
|
|
90
|
+
"""Start a drag operation with the given data."""
|
|
91
|
+
print(f"[DEBUG] Starting drag with data: {data}")
|
|
92
|
+
|
|
93
|
+
# Create mime data
|
|
94
|
+
mime_data = QMimeData()
|
|
95
|
+
json_str = json.dumps(data)
|
|
96
|
+
mime_data.setText(json_str)
|
|
97
|
+
mime_data.setData("application/json", json_str.encode('utf-8'))
|
|
98
|
+
|
|
99
|
+
# Create drag object
|
|
100
|
+
drag = QDrag(self)
|
|
101
|
+
drag.setMimeData(mime_data)
|
|
102
|
+
|
|
103
|
+
# Start drag operation
|
|
104
|
+
result = drag.exec(Qt.DropAction.CopyAction)
|
|
105
|
+
print(f"[DEBUG] Drag result: {result}")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class TestWindow(QMainWindow):
|
|
109
|
+
"""Main test window."""
|
|
110
|
+
|
|
111
|
+
def __init__(self):
|
|
112
|
+
super().__init__()
|
|
113
|
+
self.setWindowTitle("Array Format Drag & Drop Test")
|
|
114
|
+
self.setGeometry(100, 100, 800, 600)
|
|
115
|
+
self._init_ui()
|
|
116
|
+
|
|
117
|
+
def _init_ui(self):
|
|
118
|
+
"""Initialize UI."""
|
|
119
|
+
central_widget = QWidget()
|
|
120
|
+
layout = QHBoxLayout()
|
|
121
|
+
|
|
122
|
+
# Left side - drag source
|
|
123
|
+
drag_source = DragSourceWidget()
|
|
124
|
+
layout.addWidget(drag_source)
|
|
125
|
+
|
|
126
|
+
# Right side - drop targets
|
|
127
|
+
right_layout = QVBoxLayout()
|
|
128
|
+
|
|
129
|
+
# QPSACellObject drop target
|
|
130
|
+
cell_object_label = QLabel("QPSACellObject (Drop Here):")
|
|
131
|
+
right_layout.addWidget(cell_object_label)
|
|
132
|
+
|
|
133
|
+
self.cell_object = QPSACellObject()
|
|
134
|
+
self.cell_object.setMinimumHeight(200)
|
|
135
|
+
right_layout.addWidget(self.cell_object)
|
|
136
|
+
|
|
137
|
+
# QPSACellInfo drop target
|
|
138
|
+
cell_info_label = QLabel("QPSACellInfo (Drop Here):")
|
|
139
|
+
right_layout.addWidget(cell_info_label)
|
|
140
|
+
|
|
141
|
+
self.cell_info = QPSACellInfo()
|
|
142
|
+
right_layout.addWidget(self.cell_info)
|
|
143
|
+
|
|
144
|
+
# Status label
|
|
145
|
+
self.status_label = QLabel("Status: Ready")
|
|
146
|
+
right_layout.addWidget(self.status_label)
|
|
147
|
+
|
|
148
|
+
# Clear buttons
|
|
149
|
+
clear_layout = QHBoxLayout()
|
|
150
|
+
btn_clear_object = QPushButton("Clear QPSACellObject")
|
|
151
|
+
btn_clear_object.clicked.connect(self.cell_object.clear_objects)
|
|
152
|
+
clear_layout.addWidget(btn_clear_object)
|
|
153
|
+
|
|
154
|
+
btn_clear_info = QPushButton("Clear QPSACellInfo")
|
|
155
|
+
btn_clear_info.clicked.connect(self._clear_cell_info)
|
|
156
|
+
clear_layout.addWidget(btn_clear_info)
|
|
157
|
+
|
|
158
|
+
right_layout.addLayout(clear_layout)
|
|
159
|
+
|
|
160
|
+
layout.addLayout(right_layout)
|
|
161
|
+
central_widget.setLayout(layout)
|
|
162
|
+
self.setCentralWidget(central_widget)
|
|
163
|
+
|
|
164
|
+
# Connect signals
|
|
165
|
+
self.cell_object.objectAdded.connect(self._on_object_added)
|
|
166
|
+
self.cell_object.objectRemoved.connect(self._on_object_removed)
|
|
167
|
+
|
|
168
|
+
def _clear_cell_info(self):
|
|
169
|
+
"""Clear QPSACellInfo objects."""
|
|
170
|
+
self.cell_info.objects = []
|
|
171
|
+
self.status_label.setText("Status: QPSACellInfo cleared")
|
|
172
|
+
|
|
173
|
+
def _on_object_added(self, obj_data):
|
|
174
|
+
"""Handle object added to QPSACellObject."""
|
|
175
|
+
self.status_label.setText(f"Status: Object added - {obj_data.get('name', 'Unknown')}")
|
|
176
|
+
|
|
177
|
+
def _on_object_removed(self, obj_id):
|
|
178
|
+
"""Handle object removed from QPSACellObject."""
|
|
179
|
+
self.status_label.setText(f"Status: Object removed - {obj_id}")
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def main():
|
|
183
|
+
"""Main function."""
|
|
184
|
+
app = QApplication(sys.argv)
|
|
185
|
+
window = TestWindow()
|
|
186
|
+
window.show()
|
|
187
|
+
sys.exit(app.exec())
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
if __name__ == "__main__":
|
|
191
|
+
main()
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Test script for drag functionality in QPSAMapViewer
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
import os
|
|
9
|
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
|
|
10
|
+
|
|
11
|
+
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QTextEdit, QLabel
|
|
12
|
+
from PyQt6.QtCore import Qt
|
|
13
|
+
from PyQt6.QtGui import QDropEvent
|
|
14
|
+
from ui.qmapv.qmapv import QPSAMapViewer, CellInfo
|
|
15
|
+
|
|
16
|
+
class DropTarget(QWidget):
|
|
17
|
+
"""A simple drop target to test drag functionality."""
|
|
18
|
+
|
|
19
|
+
def __init__(self):
|
|
20
|
+
super().__init__()
|
|
21
|
+
self.setAcceptDrops(True)
|
|
22
|
+
self.text_edit = QTextEdit()
|
|
23
|
+
self.text_edit.setReadOnly(True)
|
|
24
|
+
self.label = QLabel("Drop target - drag data will appear here")
|
|
25
|
+
|
|
26
|
+
layout = QVBoxLayout()
|
|
27
|
+
layout.addWidget(self.label)
|
|
28
|
+
layout.addWidget(self.text_edit)
|
|
29
|
+
self.setLayout(layout)
|
|
30
|
+
|
|
31
|
+
self.setWindowTitle("Drag Test Target")
|
|
32
|
+
self.resize(400, 300)
|
|
33
|
+
|
|
34
|
+
def dragEnterEvent(self, event):
|
|
35
|
+
"""Accept drag enter events."""
|
|
36
|
+
print(f"[TEST] Drag enter event received: hasText={event.mimeData().hasText()}")
|
|
37
|
+
if event.mimeData().hasText():
|
|
38
|
+
event.acceptProposedAction()
|
|
39
|
+
|
|
40
|
+
def dropEvent(self, event):
|
|
41
|
+
"""Handle drop events."""
|
|
42
|
+
print(f"[TEST] Drop event received")
|
|
43
|
+
if event.mimeData().hasText():
|
|
44
|
+
text = event.mimeData().text()
|
|
45
|
+
self.text_edit.setPlainText(text)
|
|
46
|
+
print(f"[TEST] Received text: {text}")
|
|
47
|
+
event.acceptProposedAction()
|
|
48
|
+
|
|
49
|
+
def test_drag_functionality():
|
|
50
|
+
"""Test the drag functionality."""
|
|
51
|
+
app = QApplication(sys.argv)
|
|
52
|
+
|
|
53
|
+
# Create main window
|
|
54
|
+
main_window = QWidget()
|
|
55
|
+
main_window.setWindowTitle("Drag Test")
|
|
56
|
+
main_window.resize(1200, 800)
|
|
57
|
+
|
|
58
|
+
# Create layout
|
|
59
|
+
layout = QHBoxLayout()
|
|
60
|
+
|
|
61
|
+
# Create map viewer
|
|
62
|
+
map_viewer = QPSAMapViewer()
|
|
63
|
+
|
|
64
|
+
# Create a simple test map with some cells
|
|
65
|
+
# For testing, we'll manually add some cell info
|
|
66
|
+
test_cells = [
|
|
67
|
+
CellInfo(10, 10),
|
|
68
|
+
CellInfo(15, 15), # Empty cell for point testing
|
|
69
|
+
CellInfo(20, 20)
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
# Add objects to test cells
|
|
73
|
+
test_cells[0]._objects = [
|
|
74
|
+
{"type": "Source", "method": "Source", "id": "source1", "name": "Source 1"},
|
|
75
|
+
{"type": "Mineral", "method": "Mineral", "id": "mineral1", "name": "Mineral 1"}
|
|
76
|
+
]
|
|
77
|
+
test_cells[2]._objects = [
|
|
78
|
+
{"type": "Controller", "method": "Controller", "id": "ctrl1", "name": "Controller 1"}
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
# Set up the map viewer with test data
|
|
82
|
+
# Note: This is a simplified test - in real usage you'd load an actual map
|
|
83
|
+
|
|
84
|
+
# Create drop target
|
|
85
|
+
drop_target = DropTarget()
|
|
86
|
+
|
|
87
|
+
# Add widgets to layout
|
|
88
|
+
layout.addWidget(map_viewer, 2)
|
|
89
|
+
layout.addWidget(drop_target, 1)
|
|
90
|
+
|
|
91
|
+
main_window.setLayout(layout)
|
|
92
|
+
|
|
93
|
+
# Show windows
|
|
94
|
+
main_window.show()
|
|
95
|
+
drop_target.show()
|
|
96
|
+
|
|
97
|
+
print("[TEST] Drag test started!")
|
|
98
|
+
print("[TEST] Instructions:")
|
|
99
|
+
print("[TEST] 1. Hold Ctrl or Alt key")
|
|
100
|
+
print("[TEST] 2. Click and drag on the map")
|
|
101
|
+
print("[TEST] 3. Drop on the right panel")
|
|
102
|
+
print("[TEST] 4. Check the debug output")
|
|
103
|
+
|
|
104
|
+
sys.exit(app.exec())
|
|
105
|
+
|
|
106
|
+
if __name__ == "__main__":
|
|
107
|
+
test_drag_functionality()
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Test script for QPSACellInfo component
|
|
4
|
+
"""
|
|
5
|
+
import sys
|
|
6
|
+
import os
|
|
7
|
+
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))))
|
|
8
|
+
|
|
9
|
+
from PyQt6.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton, QHBoxLayout
|
|
10
|
+
from PyQt6.QtCore import Qt
|
|
11
|
+
from pyscreeps_arena.ui.qmapv.qcinfo import QPSACellInfo
|
|
12
|
+
from pyscreeps_arena.ui.qmapv.qmapv import CellInfo
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TestWindow(QWidget):
|
|
16
|
+
def __init__(self):
|
|
17
|
+
super().__init__()
|
|
18
|
+
self.setWindowTitle("QPSACellInfo Component Test")
|
|
19
|
+
self.setGeometry(100, 100, 400, 500)
|
|
20
|
+
self._init_ui()
|
|
21
|
+
|
|
22
|
+
def _init_ui(self):
|
|
23
|
+
"""Initialize test UI."""
|
|
24
|
+
layout = QVBoxLayout()
|
|
25
|
+
|
|
26
|
+
# Create the cell info component
|
|
27
|
+
self.cell_info = QPSACellInfo()
|
|
28
|
+
layout.addWidget(self.cell_info)
|
|
29
|
+
|
|
30
|
+
# Add test buttons
|
|
31
|
+
button_layout = QHBoxLayout()
|
|
32
|
+
|
|
33
|
+
# Test button 1 - Plain terrain with objects
|
|
34
|
+
btn1 = QPushButton("Test Plain Cell")
|
|
35
|
+
btn1.clicked.connect(self.test_plain_cell)
|
|
36
|
+
button_layout.addWidget(btn1)
|
|
37
|
+
|
|
38
|
+
# Test button 2 - Swamp terrain
|
|
39
|
+
btn2 = QPushButton("Test Swamp Cell")
|
|
40
|
+
btn2.clicked.connect(self.test_swamp_cell)
|
|
41
|
+
button_layout.addWidget(btn2)
|
|
42
|
+
|
|
43
|
+
# Test button 3 - Wall terrain
|
|
44
|
+
btn3 = QPushButton("Test Wall Cell")
|
|
45
|
+
btn3.clicked.connect(self.test_wall_cell)
|
|
46
|
+
button_layout.addWidget(btn3)
|
|
47
|
+
|
|
48
|
+
# Test button 4 - Empty cell
|
|
49
|
+
btn4 = QPushButton("Test Empty Cell")
|
|
50
|
+
btn4.clicked.connect(self.test_empty_cell)
|
|
51
|
+
button_layout.addWidget(btn4)
|
|
52
|
+
|
|
53
|
+
layout.addLayout(button_layout)
|
|
54
|
+
|
|
55
|
+
# Connect signals for testing
|
|
56
|
+
self.cell_info.itemSelected.connect(self.on_item_selected)
|
|
57
|
+
self.cell_info.itemCancelSelected.connect(self.on_item_cancel_selected)
|
|
58
|
+
self.cell_info.itemSelectChanged.connect(self.on_item_select_changed)
|
|
59
|
+
|
|
60
|
+
self.setLayout(layout)
|
|
61
|
+
|
|
62
|
+
def test_plain_cell(self):
|
|
63
|
+
"""Test with plain terrain cell."""
|
|
64
|
+
print("[DEBUG] Testing plain cell") # 调试输出
|
|
65
|
+
|
|
66
|
+
# Create test cell info
|
|
67
|
+
cell_data = CellInfo(15, 25)
|
|
68
|
+
cell_data.terrain = '2' # Plain
|
|
69
|
+
|
|
70
|
+
# Add some test objects
|
|
71
|
+
cell_data.add_object({
|
|
72
|
+
'id': 'obj1',
|
|
73
|
+
'type': 'StructureRoad',
|
|
74
|
+
'name': 'Road'
|
|
75
|
+
})
|
|
76
|
+
cell_data.add_object({
|
|
77
|
+
'id': 'obj2',
|
|
78
|
+
'type': 'StructureSpawn',
|
|
79
|
+
'name': 'Spawn'
|
|
80
|
+
})
|
|
81
|
+
cell_data.add_object({
|
|
82
|
+
'id': 'obj3',
|
|
83
|
+
'type': 'Creep',
|
|
84
|
+
'name': 'Worker'
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
# Set cell data
|
|
88
|
+
self.cell_info.data = cell_data
|
|
89
|
+
|
|
90
|
+
# Test selection states
|
|
91
|
+
self.cell_info.selects = {
|
|
92
|
+
'obj1': True,
|
|
93
|
+
'obj2': False,
|
|
94
|
+
'obj3': True
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
def test_swamp_cell(self):
|
|
98
|
+
"""Test with swamp terrain cell."""
|
|
99
|
+
print("[DEBUG] Testing swamp cell") # 调试输出
|
|
100
|
+
|
|
101
|
+
# Create test cell info
|
|
102
|
+
cell_data = CellInfo(30, 40)
|
|
103
|
+
cell_data.terrain = 'A' # Swamp
|
|
104
|
+
|
|
105
|
+
# Add some test objects
|
|
106
|
+
cell_data.add_object({
|
|
107
|
+
'id': 'swamp_obj1',
|
|
108
|
+
'type': 'StructureRoad',
|
|
109
|
+
'name': 'Swamp Road'
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
# Set cell data
|
|
113
|
+
self.cell_info.data = cell_data
|
|
114
|
+
|
|
115
|
+
def test_wall_cell(self):
|
|
116
|
+
"""Test with wall terrain cell."""
|
|
117
|
+
print("[DEBUG] Testing wall cell") # 调试输出
|
|
118
|
+
|
|
119
|
+
# Create test cell info
|
|
120
|
+
cell_data = CellInfo(50, 60)
|
|
121
|
+
cell_data.terrain = 'X' # Wall
|
|
122
|
+
|
|
123
|
+
# Add some test objects
|
|
124
|
+
cell_data.add_object({
|
|
125
|
+
'id': 'wall_obj1',
|
|
126
|
+
'type': 'StructureWall',
|
|
127
|
+
'name': 'Wall'
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
# Set cell data
|
|
131
|
+
self.cell_info.data = cell_data
|
|
132
|
+
|
|
133
|
+
def test_empty_cell(self):
|
|
134
|
+
"""Test with empty cell."""
|
|
135
|
+
print("[DEBUG] Testing empty cell") # 调试输出
|
|
136
|
+
|
|
137
|
+
# Create test cell info
|
|
138
|
+
cell_data = CellInfo(75, 85)
|
|
139
|
+
cell_data.terrain = '2' # Plain
|
|
140
|
+
|
|
141
|
+
# Set cell data (no objects)
|
|
142
|
+
self.cell_info.data = cell_data
|
|
143
|
+
|
|
144
|
+
def on_item_selected(self, obj_id):
|
|
145
|
+
"""Handle item selected signal."""
|
|
146
|
+
print(f"[DEBUG] Item selected: {obj_id}") # 调试输出
|
|
147
|
+
|
|
148
|
+
def on_item_cancel_selected(self, obj_id):
|
|
149
|
+
"""Handle item cancel selected signal."""
|
|
150
|
+
print(f"[DEBUG] Item cancel selected: {obj_id}") # 调试输出
|
|
151
|
+
|
|
152
|
+
def on_item_select_changed(self, obj_id, selected):
|
|
153
|
+
"""Handle item select changed signal."""
|
|
154
|
+
print(f"[DEBUG] Item select changed: {obj_id} -> {selected}") # 调试输出
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def main():
|
|
158
|
+
"""Main function."""
|
|
159
|
+
app = QApplication(sys.argv)
|
|
160
|
+
|
|
161
|
+
# Create and show test window
|
|
162
|
+
window = TestWindow()
|
|
163
|
+
window.show()
|
|
164
|
+
|
|
165
|
+
sys.exit(app.exec())
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
if __name__ == "__main__":
|
|
169
|
+
main()
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
QPSA Map Viewer Test Application
|
|
4
|
+
"""
|
|
5
|
+
import sys
|
|
6
|
+
import os
|
|
7
|
+
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
|
|
8
|
+
QHBoxLayout, QLabel, QTextEdit, QSplitter, QPushButton)
|
|
9
|
+
from PyQt6.QtCore import Qt, pyqtSlot
|
|
10
|
+
from PyQt6.QtGui import QFont
|
|
11
|
+
|
|
12
|
+
# Add parent directory to path for imports
|
|
13
|
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
|
|
14
|
+
|
|
15
|
+
from ui.qmapv import QPSAMapViewer, CellInfo
|
|
16
|
+
from ui.qmapv.qcinfo import QPSACellInfo
|
|
17
|
+
from ui.qmapv.qco import QPSACellObject
|
|
18
|
+
from pyscreeps_arena import config
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class MapViewerDemo(QMainWindow):
|
|
22
|
+
"""Demo application for QPSAMapViewer."""
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
super().__init__()
|
|
26
|
+
self._init_ui()
|
|
27
|
+
|
|
28
|
+
def _init_ui(self):
|
|
29
|
+
"""Initialize the UI."""
|
|
30
|
+
self.setWindowTitle("QPSA Map Viewer Demo")
|
|
31
|
+
self.setGeometry(100, 100, 1400, 800)
|
|
32
|
+
|
|
33
|
+
# Central widget
|
|
34
|
+
central_widget = QWidget()
|
|
35
|
+
self.setCentralWidget(central_widget)
|
|
36
|
+
|
|
37
|
+
# Main layout
|
|
38
|
+
main_layout = QHBoxLayout(central_widget)
|
|
39
|
+
|
|
40
|
+
# Splitter for resizable panels
|
|
41
|
+
splitter = QSplitter(Qt.Orientation.Horizontal)
|
|
42
|
+
|
|
43
|
+
# Left panel - Map viewer
|
|
44
|
+
self._map_viewer = QPSAMapViewer()
|
|
45
|
+
self._map_viewer.currentChanged.connect(self._on_current_changed)
|
|
46
|
+
self._map_viewer.selectChanged.connect(self._on_select_changed)
|
|
47
|
+
self._map_viewer.rightClicked.connect(self._on_right_clicked)
|
|
48
|
+
splitter.addWidget(self._map_viewer)
|
|
49
|
+
|
|
50
|
+
# Right panel - Info panel with QPSACellInfo components
|
|
51
|
+
info_panel = QWidget()
|
|
52
|
+
info_layout = QVBoxLayout(info_panel)
|
|
53
|
+
|
|
54
|
+
# Current cell info (hover)
|
|
55
|
+
current_group = QWidget()
|
|
56
|
+
current_layout = QVBoxLayout(current_group)
|
|
57
|
+
|
|
58
|
+
current_label = QLabel("当前单元格 (鼠标悬停)")
|
|
59
|
+
current_label.setFont(QFont("Arial", 12, QFont.Weight.Bold))
|
|
60
|
+
current_layout.addWidget(current_label)
|
|
61
|
+
|
|
62
|
+
self._current_cell_info = QPSACellInfo()
|
|
63
|
+
self._current_cell_info.setMaximumHeight(180) # Updated height constraint
|
|
64
|
+
current_layout.addWidget(self._current_cell_info)
|
|
65
|
+
|
|
66
|
+
info_layout.addWidget(current_group)
|
|
67
|
+
|
|
68
|
+
# Selected cell info (click)
|
|
69
|
+
selected_group = QWidget()
|
|
70
|
+
selected_layout = QVBoxLayout(selected_group)
|
|
71
|
+
|
|
72
|
+
selected_label = QLabel("选中单元格 (鼠标点击)")
|
|
73
|
+
selected_label.setFont(QFont("Arial", 12, QFont.Weight.Bold))
|
|
74
|
+
selected_layout.addWidget(selected_label)
|
|
75
|
+
|
|
76
|
+
self._selected_cell_info = QPSACellInfo()
|
|
77
|
+
self._selected_cell_info.setMaximumHeight(200)
|
|
78
|
+
selected_layout.addWidget(self._selected_cell_info)
|
|
79
|
+
|
|
80
|
+
info_layout.addWidget(selected_group)
|
|
81
|
+
|
|
82
|
+
# Right-clicked cell info
|
|
83
|
+
right_click_group = QWidget()
|
|
84
|
+
right_click_layout = QVBoxLayout(right_click_group)
|
|
85
|
+
|
|
86
|
+
right_click_label = QLabel("右键点击单元格")
|
|
87
|
+
right_click_label.setFont(QFont("Arial", 12, QFont.Weight.Bold))
|
|
88
|
+
right_click_layout.addWidget(right_click_label)
|
|
89
|
+
|
|
90
|
+
self._right_click_cell_info = QPSACellInfo()
|
|
91
|
+
self._right_click_cell_info.setMaximumHeight(200)
|
|
92
|
+
right_click_layout.addWidget(self._right_click_cell_info)
|
|
93
|
+
|
|
94
|
+
info_layout.addWidget(right_click_group)
|
|
95
|
+
|
|
96
|
+
# Language toggle button
|
|
97
|
+
self._lang_button = QPushButton("切换语言 (CN/EN)")
|
|
98
|
+
self._lang_button.clicked.connect(self._toggle_language)
|
|
99
|
+
info_layout.addWidget(self._lang_button)
|
|
100
|
+
|
|
101
|
+
# Instructions
|
|
102
|
+
instructions = QLabel(
|
|
103
|
+
"使用说明:\n"
|
|
104
|
+
"1. 点击'打开地图'按钮选择JSON文件\n"
|
|
105
|
+
"2. 鼠标悬停查看单元格信息\n"
|
|
106
|
+
"3. 鼠标点击选择单元格\n"
|
|
107
|
+
"4. 鼠标右键点击触发右键事件\n"
|
|
108
|
+
"5. 使用鼠标滚轮缩放地图\n"
|
|
109
|
+
"6. 拖拽地图进行平移\n"
|
|
110
|
+
"\n"
|
|
111
|
+
"注意: GameObject和Structure基础类型已被过滤,\n"
|
|
112
|
+
"但它们的子类(如StructureSpawn等)会正常显示"
|
|
113
|
+
)
|
|
114
|
+
instructions.setWordWrap(True)
|
|
115
|
+
instructions.setStyleSheet("font-size: 11px; color: #666; padding: 10px;")
|
|
116
|
+
# Cell objects component for drag and drop test
|
|
117
|
+
objects_group = QWidget()
|
|
118
|
+
objects_layout = QVBoxLayout(objects_group)
|
|
119
|
+
|
|
120
|
+
objects_label = QLabel("拖拽对象列表")
|
|
121
|
+
objects_label.setFont(QFont("Arial", 12, QFont.Weight.Bold))
|
|
122
|
+
objects_layout.addWidget(objects_label)
|
|
123
|
+
|
|
124
|
+
self._cell_objects = QPSACellObject()
|
|
125
|
+
self._cell_objects.setMinimumHeight(200)
|
|
126
|
+
objects_layout.addWidget(self._cell_objects)
|
|
127
|
+
|
|
128
|
+
info_layout.addWidget(objects_group)
|
|
129
|
+
|
|
130
|
+
info_layout.addWidget(instructions)
|
|
131
|
+
|
|
132
|
+
info_layout.addStretch()
|
|
133
|
+
|
|
134
|
+
splitter.addWidget(info_panel)
|
|
135
|
+
splitter.setSizes([1024, 376])
|
|
136
|
+
|
|
137
|
+
main_layout.addWidget(splitter)
|
|
138
|
+
|
|
139
|
+
# Try to load default map if available
|
|
140
|
+
default_map = os.path.join(os.path.dirname(__file__), '..', '..', 'map.json')
|
|
141
|
+
if os.path.exists(default_map):
|
|
142
|
+
try:
|
|
143
|
+
self._map_viewer.load_map(default_map)
|
|
144
|
+
except Exception as e:
|
|
145
|
+
print(f"[DEBUG] Failed to load default map: {e}") # 调试输出
|
|
146
|
+
|
|
147
|
+
@pyqtSlot(object)
|
|
148
|
+
def _on_current_changed(self, cell_info):
|
|
149
|
+
"""Handle current cell change."""
|
|
150
|
+
self._current_cell_info.data = cell_info
|
|
151
|
+
# Set map image for object icons
|
|
152
|
+
self._current_cell_info.image = self._map_viewer.image
|
|
153
|
+
print(f"[DEBUG] Current cell updated: {cell_info}") # 调试输出
|
|
154
|
+
|
|
155
|
+
@pyqtSlot(object)
|
|
156
|
+
def _on_select_changed(self, cell_info):
|
|
157
|
+
"""Handle selected cell change."""
|
|
158
|
+
self._selected_cell_info.data = cell_info
|
|
159
|
+
# Set map image for object icons
|
|
160
|
+
self._selected_cell_info.image = self._map_viewer.image
|
|
161
|
+
print(f"[DEBUG] Selected cell updated: {cell_info}") # 调试输出
|
|
162
|
+
|
|
163
|
+
@pyqtSlot(object)
|
|
164
|
+
def _on_right_clicked(self, cell_info):
|
|
165
|
+
"""Handle right-click events."""
|
|
166
|
+
self._right_click_cell_info.data = cell_info
|
|
167
|
+
# Set map image for object icons
|
|
168
|
+
self._right_click_cell_info.image = self._map_viewer.image
|
|
169
|
+
print(f"[DEBUG] Right-click cell updated: {cell_info}") # 调试输出
|
|
170
|
+
|
|
171
|
+
@pyqtSlot(str)
|
|
172
|
+
def _on_item_selected(self, obj_id):
|
|
173
|
+
"""Handle object selection in QPSACellInfo."""
|
|
174
|
+
print(f"[DEBUG] Object selected: {obj_id}") # 调试输出
|
|
175
|
+
|
|
176
|
+
@pyqtSlot(str)
|
|
177
|
+
def _on_item_cancel_selected(self, obj_id):
|
|
178
|
+
"""Handle object deselection in QPSACellInfo."""
|
|
179
|
+
print(f"[DEBUG] Object deselected: {obj_id}") # 调试输出
|
|
180
|
+
|
|
181
|
+
@pyqtSlot(str, bool)
|
|
182
|
+
def _on_item_select_changed(self, obj_id, selected):
|
|
183
|
+
"""Handle object selection change in QPSACellInfo."""
|
|
184
|
+
print(f"[DEBUG] Object selection changed: {obj_id} -> {selected}") # 调试输出
|
|
185
|
+
|
|
186
|
+
@pyqtSlot()
|
|
187
|
+
def _toggle_language(self):
|
|
188
|
+
"""Toggle language between CN and EN."""
|
|
189
|
+
config.language = 'en' if config.language == 'cn' else 'cn'
|
|
190
|
+
print(f"[DEBUG] Language switched to: {config.language}") # 调试输出:查看语言切换
|
|
191
|
+
|
|
192
|
+
# Update button text
|
|
193
|
+
self._lang_button.setText("切换语言 (CN/EN)" if config.language == 'cn' else "Switch Language (CN/EN)")
|
|
194
|
+
|
|
195
|
+
# Reload current map to refresh UI text
|
|
196
|
+
current_map = self._map_viewer._current_map_path if hasattr(self._map_viewer, '_current_map_path') else None
|
|
197
|
+
if current_map and os.path.exists(current_map):
|
|
198
|
+
self._map_viewer.load_map(current_map)
|
|
199
|
+
else:
|
|
200
|
+
# Reset to default state to show new language
|
|
201
|
+
self._map_viewer._reset_to_default_state()
|
|
202
|
+
|
|
203
|
+
def closeEvent(self, event):
|
|
204
|
+
"""Clean up when closing."""
|
|
205
|
+
self._map_viewer.cleanup()
|
|
206
|
+
event.accept()
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def main():
|
|
210
|
+
"""Main function."""
|
|
211
|
+
app = QApplication(sys.argv)
|
|
212
|
+
|
|
213
|
+
# Set application style
|
|
214
|
+
app.setStyle('Fusion')
|
|
215
|
+
|
|
216
|
+
# Create and show demo
|
|
217
|
+
demo = MapViewerDemo()
|
|
218
|
+
demo.show()
|
|
219
|
+
|
|
220
|
+
sys.exit(app.exec())
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
if __name__ == '__main__':
|
|
224
|
+
main()
|