Skip to content

Commit 74fbac7

Browse files
committed
Basic map editor outliner
Missing a lot of features from the C++ version. WIll implement fully once map import and project serialization are working.
1 parent 280c6c4 commit 74fbac7

File tree

2 files changed

+152
-2
lines changed

2 files changed

+152
-2
lines changed

src/Gui/Documents/MapEditorDocument.bf

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ namespace Nanoforge.Gui.Documents
2222
private StringView _loadFailureReason = .();
2323
public Territory Map = null;
2424
private Scene _scene = null;
25+
private ZoneObject _selectedObject;
26+
private Zone _selectedZone = null;
27+
28+
//Deepest tree level the outliner will draw. Need to limit to prevent accidental stack overflow
29+
private const int MAX_OUTLINER_DEPTH = 7;
2530

2631
public this(StringView mapName)
2732
{
@@ -180,7 +185,151 @@ namespace Nanoforge.Gui.Documents
180185

181186
public override void Outliner(App app, Gui gui)
182187
{
188+
if (Loading)
189+
{
190+
ImGui.Text("Map is loading...");
191+
return;
192+
}
193+
194+
//Set custom highlight colors for the table
195+
Vec4<f32> selectedColor = .(0.157f, 0.350f, 0.588f, 1.0f);
196+
Vec4<f32> highlightedColor = selectedColor * 1.1f;
197+
ImGui.PushStyleColor(.Header, selectedColor);
198+
ImGui.PushStyleColor(.HeaderHovered, highlightedColor);
199+
ImGui.PushStyleColor(.HeaderActive, highlightedColor);
200+
ImGui.TableFlags tableFlags = .ScrollY | .ScrollX | .RowBg | .BordersOuter | .BordersV | .Resizable | .Reorderable | .Hideable | .SizingFixedFit;
201+
if (ImGui.BeginTable("ZoneObjectTable", 4, tableFlags))
202+
{
203+
ImGui.TableSetupScrollFreeze(0, 1);
204+
ImGui.TableSetupColumn("Name");
205+
ImGui.TableSetupColumn("Flags");
206+
ImGui.TableSetupColumn("Num");
207+
ImGui.TableSetupColumn("Handle");
208+
ImGui.TableHeadersRow();
209+
210+
//Loop through visible zones
211+
bool anyZoneHovered = false;
212+
for (Zone zone in Map.Zones)
213+
{
214+
ImGui.TableNextRow();
215+
ImGui.TableNextColumn();
216+
217+
bool anyChildrenVisible = Outliner_ZoneAnyChildObjectsVisible(zone);
218+
if (!anyChildrenVisible)
219+
continue;
220+
221+
bool selected = (zone == _selectedZone);
222+
ImGui.TreeNodeFlags nodeFlags = .SpanAvailWidth | (anyChildrenVisible ? .None : .Leaf);
223+
if (selected)
224+
nodeFlags |= .Selected;
225+
226+
//Draw tree node for zones if there's > 1. Otherwise draw the objects at the root of the tree
227+
bool singleZone = Map.Zones.Count == 1;
228+
bool treeNodeOpen = false;
229+
if (!singleZone)
230+
{
231+
treeNodeOpen = ImGui.TreeNodeEx(zone.Name.CStr(), nodeFlags);
232+
}
233+
234+
if (singleZone || treeNodeOpen)
235+
{
236+
for (ZoneObject obj in zone.Objects)
237+
{
238+
//Don't draw objects with parents at the top of the tree. They'll be drawn as subnodes of their parent
239+
if (obj.Parent != null)
240+
continue;
241+
242+
int depth = 0;
243+
Outliner_DrawObjectNode(obj, depth + 1);
244+
}
245+
}
246+
247+
if (treeNodeOpen)
248+
ImGui.TreePop();
249+
}
250+
251+
ImGui.EndTable();
252+
}
253+
254+
ImGui.PopStyleColor(3);
255+
}
256+
257+
private bool Outliner_ZoneAnyChildObjectsVisible(Zone zone)
258+
{
259+
//TODO: Implement
260+
return true;
261+
}
262+
263+
private bool Outliner_ShowObjectOrChildren(ZoneObject obj)
264+
{
265+
//TODO: Implement
266+
return true;
267+
}
268+
269+
private void Outliner_DrawObjectNode(ZoneObject obj, int depth)
270+
{
271+
if (depth > MAX_OUTLINER_DEPTH)
272+
{
273+
ImGui.Text("Can't draw object! Hit outliner depth limit");
274+
return;
275+
}
276+
277+
bool show = Outliner_ShowObjectOrChildren(obj);
278+
if (!show)
279+
return;
280+
281+
bool selected = (obj == _selectedObject);
282+
String label = scope .();
283+
if (obj.GetName() case .Ok(let name))
284+
label.Set(name);
285+
else
286+
label.Set(obj.Classname);
287+
288+
ImGui.TableNextRow();
289+
ImGui.TableNextColumn();
183290

291+
bool hasChildren = obj.Children.Count > 0;
292+
bool hasParent = obj.Parent != null;
293+
294+
//Draw node
295+
ImGui.PushID(Internal.UnsafeCastToPtr(obj));
296+
f32 nodeXPos = ImGui.GetCursorPosX();
297+
bool nodeOpen = ImGui.TreeNodeEx(label.CStr(), .SpanAvailWidth | .OpenOnDoubleClick | .OpenOnArrow | (hasChildren ? .None : .Leaf) | (selected ? .Selected : .None));
298+
299+
if (ImGui.IsItemClicked())
300+
{
301+
if (obj == _selectedObject)
302+
_selectedObject = null;
303+
else
304+
_selectedObject = obj;
305+
}
306+
if (ImGui.IsItemHovered())
307+
{
308+
ImGui.TooltipOnPrevious(obj.Classname);
309+
}
310+
311+
//Flags
312+
ImGui.TableNextColumn();
313+
ImGui.Text(obj.Flags.ToString(.. scope .()));
314+
315+
//Num
316+
ImGui.TableNextColumn();
317+
ImGui.Text(obj.Num.ToString(.. scope .()));
318+
319+
//Handle
320+
ImGui.TableNextColumn();
321+
ImGui.Text(obj.Handle.ToString(.. scope .()));
322+
323+
//Draw child nodes
324+
if (nodeOpen)
325+
{
326+
for (ZoneObject child in obj.Children)
327+
{
328+
Outliner_DrawObjectNode(child, depth + 1);
329+
}
330+
ImGui.TreePop();
331+
}
332+
ImGui.PopID();
184333
}
185334

186335
public override void Inspector(App app, Gui gui)

src/Gui/Panels/MainMenuBar.bf

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ namespace Nanoforge.Gui.Panels
191191
if (FirstDraw)
192192
{
193193
ImGui.ID dockLeftId = ImGui.DockBuilderSplitNode(DockspaceId, .Left, 0.20f, var outIdLeft, out DockspaceId);
194-
ImGui.ID dockRightId = ImGui.DockBuilderSplitNode(DockspaceId, .Right, 0.28f, var outIdRight, out DockspaceId);
194+
ImGui.ID dockLeftBottomId = ImGui.DockBuilderSplitNode(dockLeftId, .Down, 0.5f, var outIdBottom, out dockLeftId);
195+
//ImGui.ID dockRightId = ImGui.DockBuilderSplitNode(DockspaceId, .Right, 0.28f, var outIdRight, out DockspaceId);
195196
//ImGui.ID dockRightUp = ImGui.DockBuilderSplitNode(dockRightId, .Up, 0.35f, var outIdRightUp, out dockRightId);
196197
DockspaceCentralNodeId = ImGui.DockBuilderGetCentralNode(DockspaceId).ID;
197198
ImGui.ID dockCentralDownSplitId = ImGui.DockBuilderSplitNode(DockspaceCentralNodeId, .Down, 0.20f, var outIdCentralDown, out DockspaceCentralNodeId);
@@ -202,7 +203,7 @@ namespace Nanoforge.Gui.Panels
202203
ImGui.DockBuilderDockWindow("Dear ImGui Demo", dockLeftId);
203204
ImGui.DockBuilderDockWindow(StateViewer.ID.Ptr, dockLeftId);
204205
ImGui.DockBuilderDockWindow(gui.OutlinerIdentifier, dockLeftId);
205-
ImGui.DockBuilderDockWindow(gui.InspectorIdentifier, dockRightId);
206+
ImGui.DockBuilderDockWindow(gui.InspectorIdentifier, dockLeftBottomId);
206207
ImGui.DockBuilderDockWindow("Log", dockCentralDownSplitId);
207208
}
208209
}

0 commit comments

Comments
 (0)