Skip to content

Commit b5770d2

Browse files
committed
Rewrote hierarchy
1 parent 44fcb1b commit b5770d2

File tree

3 files changed

+137
-59
lines changed

3 files changed

+137
-59
lines changed

editor/app.py

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -23,47 +23,6 @@ def __init__(self, path):
2323
self.window = Window(self)
2424
self.window.set_icon("icons/icon.png")
2525

26-
self.window.toolbar.add_action("New", "File", "Ctrl+N", "Create a new project", testing("new"))
27-
self.window.toolbar.add_action("Open", "File", "Ctrl+O", "Open an existing project", self.open)
28-
self.window.toolbar.add_action("Save", "File", "Ctrl+S", "Save the current Scene", self.save)
29-
self.window.toolbar.add_action("Save As", "File", "Ctrl+Shift+S", "Save the current Scene as new file", testing("save as"))
30-
self.window.toolbar.add_action("Save a Copy As", "File", "Ctrl+Alt+S", "Save a copy of the current Scene", testing("save copy as"))
31-
self.window.toolbar.add_separator("File")
32-
self.window.toolbar.add_action("Close Scene", "File", "Ctrl+W", "Closes the current Scene", testing("close"))
33-
self.window.toolbar.add_action("Close All", "File", "Ctrl+Shift+W", "Closes all opened Scene", testing("close all"))
34-
self.window.toolbar.add_separator("File")
35-
self.window.toolbar.add_action("Quit", "File", "Ctrl+Q", "Close the Editor", self.quit_wrapper)
36-
37-
self.window.toolbar.add_action("Undo", "Edit", "Ctrl+Z", "Undo the last action", testing("undo"))
38-
self.window.toolbar.add_action("Redo", "Edit", "Ctrl+Shift+Z", "Redo the last action", testing("redo"))
39-
self.window.toolbar.add_separator("Edit")
40-
self.window.toolbar.add_action("Cut", "Edit", "Ctrl+X", "Deletes item and adds to clipboard", testing("cut"))
41-
self.window.toolbar.add_action("Copy", "Edit", "Ctrl+C", "Adds item to clipboard", testing("copy"))
42-
self.window.toolbar.add_action("Paste", "Edit", "Ctrl+V", "Pastes item from clipboard", testing("paste"))
43-
self.window.toolbar.add_separator("Edit")
44-
self.window.toolbar.add_action("Rename", "Edit", "F2", "Renames the selected item", testing("rename"))
45-
self.window.toolbar.add_action("Duplicate", "Edit", "Ctrl+D", "Duplicates the selected item(s)", testing("duplicate"))
46-
self.window.toolbar.add_action("Delete", "Edit", "Delete", "Deletes item", testing("delete"))
47-
self.window.toolbar.add_separator("Edit")
48-
self.window.toolbar.add_action("Select All", "Edit", "Ctrl+A", "Selects all items in the current Scene", testing("select all"))
49-
self.window.toolbar.add_action("Select None", "Edit", "Escape", "Deselects all items", self.window.select_none)
50-
51-
self.window.toolbar.add_sub_action("Folder", "Assets", "Create", "", "", testing("new folder"))
52-
self.window.toolbar.add_sub_action("File", "Assets", "Create", "", "", testing("new file"))
53-
self.window.toolbar.add_sub_separator("Assets", "Create")
54-
self.window.toolbar.add_sub_action("Script", "Assets", "Create", "", "", testing("new script"))
55-
self.window.toolbar.add_sub_separator("Assets", "Create")
56-
self.window.toolbar.add_sub_action("Scene", "Assets", "Create", "", "", testing("new scene"))
57-
self.window.toolbar.add_sub_action("Prefab", "Assets", "Create", "", "", testing("new prefab"))
58-
self.window.toolbar.add_sub_action("Material", "Assets", "Create", "", "", testing("new mat"))
59-
self.window.toolbar.add_sub_separator("Assets", "Create")
60-
self.window.toolbar.add_sub_action("Physic Material", "Assets", "Create", "", "", testing("new phys mat"))
61-
62-
self.window.toolbar.add_action("Open", "Assets", "", "Opens the selected asset", testing("open asset"))
63-
self.window.toolbar.add_action("Delete", "Assets", "", "Deletes the selected asset", testing("del asset"))
64-
65-
self.window.toolbar.add_action("Toggle Theme", "Window", "Ctrl+L", "Toggle theme between light and dark", self.window.toggle_theme)
66-
6726
self.buttons = SceneButtons(self.window)
6827
self.buttons.add_button("play.png", "Run the scene")
6928
self.buttons.add_button("pause.png", "Pause the scene")
@@ -100,6 +59,8 @@ def __init__(self, path):
10059
self.console_content.add_entry(time.strftime("%Y-%m-%d %H:%M:%S"), Logger.OUTPUT, "Test")
10160
self.game_content.console = self.console_content
10261

62+
self.setup_toolbar()
63+
10364
def start(self):
10465
self.window.showMaximized()
10566
os.environ["PYUNITY_EDITOR_LOADED"] = "1"
@@ -123,3 +84,46 @@ def quit_wrapper(self):
12384
ret = message_box.exec()
12485
if ret == QMessageBox.Ok:
12586
self.quit()
87+
88+
def setup_toolbar(self):
89+
self.window.toolbar.add_action("New", "File", "Ctrl+N", "Create a new project", testing("new"))
90+
self.window.toolbar.add_action("Open", "File", "Ctrl+O", "Open an existing project", self.open)
91+
self.window.toolbar.add_action("Save", "File", "Ctrl+S", "Save the current Scene", self.save)
92+
self.window.toolbar.add_action("Save As", "File", "Ctrl+Shift+S", "Save the current Scene as new file", testing("save as"))
93+
self.window.toolbar.add_action("Save a Copy As", "File", "Ctrl+Alt+S", "Save a copy of the current Scene", testing("save copy as"))
94+
self.window.toolbar.add_separator("File")
95+
self.window.toolbar.add_action("Close Scene", "File", "Ctrl+W", "Closes the current Scene", testing("close"))
96+
self.window.toolbar.add_action("Close All", "File", "Ctrl+Shift+W", "Closes all opened Scene", testing("close all"))
97+
self.window.toolbar.add_separator("File")
98+
self.window.toolbar.add_action("Quit", "File", "Ctrl+Q", "Close the Editor", self.quit_wrapper)
99+
100+
self.window.toolbar.add_action("Undo", "Edit", "Ctrl+Z", "Undo the last action", testing("undo"))
101+
self.window.toolbar.add_action("Redo", "Edit", "Ctrl+Shift+Z", "Redo the last action", testing("redo"))
102+
self.window.toolbar.add_separator("Edit")
103+
self.window.toolbar.add_action("Cut", "Edit", "Ctrl+X", "Deletes item and adds to clipboard", testing("cut"))
104+
self.window.toolbar.add_action("Copy", "Edit", "Ctrl+C", "Adds item to clipboard", testing("copy"))
105+
self.window.toolbar.add_action("Paste", "Edit", "Ctrl+V", "Pastes item from clipboard", testing("paste"))
106+
self.window.toolbar.add_separator("Edit")
107+
self.window.toolbar.add_action("Rename", "Edit", "F2", "Renames the selected item", testing("rename"))
108+
self.window.toolbar.add_action("Duplicate", "Edit", "Ctrl+D", "Duplicates the selected item(s)", testing("duplicate"))
109+
self.window.toolbar.add_action("Delete", "Edit", "Delete", "Deletes item", self.hierarchy_content.remove)
110+
self.window.toolbar.add_separator("Edit")
111+
self.window.toolbar.add_action("Select All", "Edit", "Ctrl+A", "Selects all items in the current Scene", self.hierarchy_content.tree_widget.selectAll)
112+
self.window.toolbar.add_action("Select None", "Edit", "Escape", "Deselects all items", self.window.select_none)
113+
114+
self.window.toolbar.add_sub_action("Folder", "Assets", "Create", "", "", testing("new folder"))
115+
self.window.toolbar.add_sub_action("File", "Assets", "Create", "", "", testing("new file"))
116+
self.window.toolbar.add_sub_separator("Assets", "Create")
117+
self.window.toolbar.add_sub_action("Script", "Assets", "Create", "", "", testing("new script"))
118+
self.window.toolbar.add_sub_separator("Assets", "Create")
119+
self.window.toolbar.add_sub_action("Scene", "Assets", "Create", "", "", testing("new scene"))
120+
self.window.toolbar.add_sub_action("Prefab", "Assets", "Create", "", "", testing("new prefab"))
121+
self.window.toolbar.add_sub_action("Material", "Assets", "Create", "", "", testing("new mat"))
122+
self.window.toolbar.add_sub_separator("Assets", "Create")
123+
self.window.toolbar.add_sub_action("Physic Material", "Assets", "Create", "", "", testing("new phys mat"))
124+
125+
self.window.toolbar.add_action("Open", "Assets", "", "Opens the selected asset", testing("open asset"))
126+
self.window.toolbar.add_action("Delete", "Assets", "", "Deletes the selected asset", testing("del asset"))
127+
128+
self.window.toolbar.add_action("Toggle Theme", "Window", "Ctrl+L", "Toggle theme between light and dark", self.window.toggle_theme)
129+

editor/inspector.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,22 @@ def isfloat(string):
2323

2424
class Inspector(QWidget):
2525
props = [pyu.ShowInInspector(str, "", "name"), pyu.ShowInInspector(int, "", "tag")]
26+
font = QFont("Segoe UI", 12)
2627
def __init__(self, parent):
2728
super(Inspector, self).__init__(parent)
2829
self.vbox_layout = QVBoxLayout(self)
2930
self.vbox_layout.setContentsMargins(0, 0, 0, 0)
3031
self.setLayout(self.vbox_layout)
3132
self.sections = []
33+
34+
self.buffer = self.add_buffer("Select a GameObject in the Hiearchy tab to view its properties.")
35+
36+
def add_buffer(self, text):
37+
label = QLabel(text)
38+
label.setWordWrap(True)
39+
label.setFont(self.__class__.font)
40+
self.vbox_layout.addWidget(label)
41+
return label
3242

3343
def add_section(self, component):
3444
section = InspectorSection(component.__class__.__name__, self)
@@ -38,26 +48,33 @@ def add_section(self, component):
3848
self.vbox_layout.addWidget(section)
3949
return section
4050

41-
def load(self, hieararchyItem):
42-
self.gameObject = hieararchyItem.gameObject
51+
def load(self, hierarchyItem):
4352
if len(self.sections):
4453
list(self.sections[0].fields.keys())[0].edited.disconnect()
4554
num = len(self.sections)
4655
self.sections = []
56+
if self.buffer is not None:
57+
num += 1
58+
self.buffer = None
4759
for i in range(num):
4860
item = self.vbox_layout.takeAt(0)
4961
widget = item.widget()
5062
self.vbox_layout.removeItem(item)
5163
widget.deleteLater()
52-
if hieararchyItem.gameObject is None:
64+
if hierarchyItem == []:
65+
self.buffer = self.add_buffer("Select a single item to view its properties.")
66+
return
67+
elif hierarchyItem is None:
68+
self.buffer = self.add_buffer("Select a GameObject in the Hiearchy tab to view its properties.")
5369
return
54-
main_section = self.add_section(hieararchyItem.gameObject)
55-
main_section.component = hieararchyItem.gameObject
56-
name_input = main_section.add_value("name", self.props[0], hieararchyItem.gameObject.name)
57-
name_input.edited.connect(hieararchyItem.rename)
58-
tag_input = main_section.add_value("tag", self.props[1], hieararchyItem.gameObject.tag.tag)
70+
self.gameObject = hierarchyItem.gameObject
71+
main_section = self.add_section(self.gameObject)
72+
main_section.component = self.gameObject
73+
name_input = main_section.add_value("name", self.props[0], self.gameObject.name)
74+
name_input.edited.connect(hierarchyItem.rename)
75+
tag_input = main_section.add_value("tag", self.props[1], self.gameObject.tag.tag)
5976
tag_input.prevent_modify = True # temporarily until i implement tag dropdowns
60-
for component in hieararchyItem.gameObject.components:
77+
for component in self.gameObject.components:
6178
section = self.add_section(component)
6279
for name, val in component.shown.items():
6380
section.add_value(name, val, getattr(component, name))

editor/views.py

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
2-
from PyQt5.QtCore import Qt
2+
import pyunity as pyu
3+
from PyQt5.QtCore import QItemSelectionModel, QModelIndex, Qt
34
from PyQt5.QtGui import QIcon
45
from PyQt5.QtWidgets import *
56

@@ -44,21 +45,53 @@ def __init__(self, parent):
4445
self.add_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
4546

4647
self.menu = QMenu()
47-
self.menu.addAction("New GameObject")
48-
self.menu.addAction("New Child GameObject")
48+
self.menu.addAction("New Root GameObject", self.new)
49+
self.menu.addAction("New Child GameObject", self.new_child)
50+
self.menu.addAction("New Sibling GameObject", self.new_sibling)
4951
self.add_button.setMenu(self.menu)
5052

5153
self.hbox_layout.addWidget(self.add_button)
5254
self.vbox_layout.addLayout(self.hbox_layout)
5355

5456
self.items = []
55-
self.tree_widget = QTreeWidget(self)
57+
self.tree_widget = CustomTreeWidget(self)
5658
self.vbox_layout.addWidget(self.tree_widget)
57-
self.tree_widget.header().setVisible(False)
58-
self.tree_widget.setIndentation(10)
59-
self.tree_widget.itemClicked.connect(self.on_click)
59+
self.tree_widget.itemSelectionChanged.connect(self.on_click)
6060
self.inspector = None
6161

62+
def new(self):
63+
new = pyu.GameObject("GameObject")
64+
self.loaded.Add(new)
65+
self.add_item(new)
66+
67+
def new_child(self):
68+
item = self.tree_widget.currentItem()
69+
if item is None:
70+
return self.new()
71+
parent = item.gameObject
72+
new = pyu.GameObject("GameObject", parent)
73+
self.loaded.Add(new)
74+
self.add_item(new, item)
75+
76+
def new_sibling(self):
77+
sibling = self.tree_widget.currentItem()
78+
if sibling is None:
79+
return self.new()
80+
item = sibling.parent()
81+
if item is None:
82+
return self.new()
83+
parent = item.gameObject
84+
new = pyu.GameObject("GameObject", parent)
85+
self.loaded.Add(new)
86+
self.add_item(new, item)
87+
88+
def remove(self):
89+
item = self.tree_widget.currentItem()
90+
if item is None:
91+
print("Nothing selected")
92+
return
93+
print("Removing " + item.gameObject.name)
94+
6295
def add_item(self, gameObject, parent=None):
6396
item = HierarchyItem(gameObject)
6497
if parent is None:
@@ -89,5 +122,29 @@ def load_scene(self, scene):
89122
self.add_item(gameObject,
90123
items[gameObject.transform.parent.gameObject])
91124

92-
def on_click(self, item, column):
93-
self.inspector.load(item)
125+
def on_click(self):
126+
items = self.tree_widget.selectedItems()
127+
if len(items) > 1:
128+
self.inspector.load([])
129+
elif len(items) == 0:
130+
self.inspector.load(None)
131+
else:
132+
self.inspector.load(items[0])
133+
134+
class CustomTreeWidget(QTreeWidget):
135+
def __init__(self, parent):
136+
super(CustomTreeWidget, self).__init__(parent)
137+
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
138+
self.header().setVisible(False)
139+
self.setIndentation(10)
140+
141+
# def mousePressEvent(self, event):
142+
# item = self.indexAt(event.pos())
143+
# selected = self.selectionModel().isSelected(item)
144+
# super(CustomTreeWidget, self).mousePressEvent(event)
145+
# if (item.row() == -1 and item.column() == -1) or selected:
146+
# self.clearSelection()
147+
# self.selectionModel().setCurrentIndex(QModelIndex(), QItemSelectionModel.Select)
148+
149+
def mouseMoveEvent(self, event):
150+
event.accept()

0 commit comments

Comments
 (0)