Skip to content

Commit

Permalink
Started to work on prefab asset editors...
Browse files Browse the repository at this point in the history
  • Loading branch information
isadorasophia committed Dec 13, 2023
1 parent d92624f commit 41b92c1
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 21 deletions.
3 changes: 0 additions & 3 deletions src/Murder.Editor/CustomEditors/CharacterEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
using Murder.Editor.Reflection;
using Murder.Editor.Stages;
using Murder.Editor.Systems;
using Murder.Editor.Utilities;
using Murder.Editor.Utilities.Attributes;
using Newtonsoft.Json.Linq;
using System;

namespace Murder.Editor.CustomEditors
{
Expand Down
3 changes: 0 additions & 3 deletions src/Murder.Editor/CustomEditors/LocalizationAssetEditor.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using ImGuiNET;
using Murder.Assets;
using Murder.Assets.Localization;
using Murder.Core.Graphics;
using Murder.Diagnostics;
Expand All @@ -8,8 +7,6 @@
using Murder.Editor.Reflection;
using Murder.Editor.Utilities;
using Murder.Editor.Utilities.Serialization;
using System;
using System.Collections.Immutable;
using System.Numerics;

namespace Murder.Editor.CustomEditors
Expand Down
128 changes: 128 additions & 0 deletions src/Murder.Editor/CustomEditors/SpriteEditor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using ImGuiNET;
using Murder.Assets.Graphics;
using Murder.Components;
using Murder.Core;
using Murder.Core.Geometry;
using Murder.Core.Graphics;
using Murder.Diagnostics;
using Murder.Editor.Attributes;
using Murder.Editor.ImGuiExtended;
using Murder.Editor.Stages;
using Murder.Editor.Systems;
using Murder.Utilities;
using System.Numerics;

namespace Murder.Editor.CustomEditors
{
[CustomEditorOf(typeof(SpriteAsset))]
internal class SpriteEditor : CustomEditor
{
/// <summary>
/// Tracks the dialog system editors across different guids.
/// </summary>
protected Dictionary<Guid, SpriteInformation> ActiveEditors { get; private set; } = new();

private SpriteAsset? _sprite = null;

public override object Target => _sprite!;

public override void OpenEditor(ImGuiRenderer imGuiRenderer, RenderContext renderContext, object target, bool overwrite)
{
_sprite = (SpriteAsset)target;

if (!ActiveEditors.ContainsKey(_sprite.Guid))
{
Stage stage = new(imGuiRenderer, renderContext);

SpriteInformation info = new(stage);
ActiveEditors[_sprite.Guid] = info;

InitializeStage(stage, info);
}
}

private void InitializeStage(Stage stage, SpriteInformation info)
{
GameLogger.Verify(_sprite is not null);

stage.ToggleSystem(typeof(EntitiesSelectorSystem), false);

Portrait portrait = new(_sprite.Guid, _sprite.Animations.Count == 0 ? string.Empty : _sprite.Animations.First().Key);
info.HelperId = stage.AddEntityWithoutAsset(new PositionComponent(), new SpriteComponent(portrait));

stage.ShowInfo = false;
stage.EditorHook.DrawSelection = false;
stage.EditorHook.CurrentZoomLevel = 5;
}

public override void DrawEditor()
{
GameLogger.Verify(_sprite is not null);

if (!ActiveEditors.TryGetValue(_sprite.Guid, out var info))
{
GameLogger.Warning("Unitialized stage for particle editor?");
return;
}

Vector2 windowSize = ImGui.GetContentRegionAvail();

using TableMultipleColumns table = new(
$"sprite_stage_{_sprite.Guid}", ImGuiTableFlags.Resizable, Calculator.RoundToInt(windowSize.X / 5), -1, Calculator.RoundToInt(windowSize.X / 5));

ImGui.TableNextColumn();

DrawFistColumn();

ImGui.TableNextColumn();

Stage stage = info.Stage;

if (ActiveEditors.ContainsKey(_sprite.Guid))
{
windowSize = ImGui.GetContentRegionAvail();
Vector2 origin = ImGui.GetItemRectMin();
float length = windowSize.X / 3f;

stage.Draw();
}

ImGui.TableNextRow();
ImGui.TableNextColumn();
}

private void DrawFistColumn()
{
GameLogger.Verify(_sprite is not null);


Vector2 windowSize = ImGui.GetContentRegionAvail();
ImGui.PushID("somed");
ImGui.PushItemWidth(20);
ImGui.TextColored(Game.Profile.Theme.Accent, $"\uf520 {_sprite.Name}");
ImGuiHelpers.PrettySelectableWithIcon(
label: _sprite.Name,
selectable: true);
ImGui.PopItemWidth();
ImGui.PopID();
}

public override void CloseEditor(Guid target)
{
if (ActiveEditors.TryGetValue(target, out SpriteInformation? info))
{
info.Stage.Dispose();
}

ActiveEditors.Remove(target);
}

protected record SpriteInformation(Stage Stage)
{
/// <summary>
/// This is the entity id in the world.
/// </summary>
public int HelperId = 0;
}
}
}
17 changes: 9 additions & 8 deletions src/Murder.Editor/Stage/Stage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ private void InitializeDrawAndWorld()
_world.Start();
}

public void Draw()
public void Draw(Rectangle? rectToDrawStage = null)
{
if (!_calledStart)
{
Expand All @@ -84,7 +84,11 @@ public void Draw()
Architect.Input.MouseConsumed = false;
}

Vector2 size = ImGui.GetItemRectSize() - new Vector2(0, 5);
Vector2 topLeft = rectToDrawStage?.TopLeft ?? ImGui.GetItemRectMin();
Vector2 bottomRight = rectToDrawStage?.BottomRight ?? ImGui.GetItemRectMax();

Vector2 size = rectToDrawStage?.Size ?? Rectangle.FromCoordinates(topLeft, bottomRight).Size;

if (size.X <= 0 || size.Y <= 0)
{
// Empty.
Expand Down Expand Up @@ -118,16 +122,13 @@ public void Draw()
}
}

var topLeft = ImGui.GetItemRectMin();
if (_world.GetUnique<EditorComponent>() is EditorComponent editorComponent)
{
editorComponent.EditorHook.Offset = ImGui.GetItemRectMin().Point();
Vector2 rectSize = ImGui.GetItemRectSize();
editorComponent.EditorHook.StageSize = rectSize;
editorComponent.EditorHook.Offset = topLeft.Point();
editorComponent.EditorHook.StageSize = rectToDrawStage?.Size ??
Rectangle.FromCoordinates(topLeft, bottomRight).Size;
}

Vector2 bottomRight = ImGui.GetItemRectMax();

ImDrawListPtr drawList = ImGui.GetWindowDrawList();
drawList.PushClipRect(topLeft, bottomRight);

Expand Down
15 changes: 8 additions & 7 deletions src/Murder/Core/Geometry/Rectangle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,9 @@ public Vector2 Size
public static implicit operator Microsoft.Xna.Framework.Rectangle(Rectangle p) => new(Calculator.RoundToInt(p.X), Calculator.RoundToInt(p.Y), Calculator.RoundToInt(p.Width), Calculator.RoundToInt(p.Height));

/// <summary>
/// Constructor for a rectangle
/// Constructor for a rectangle from a set of coordinates.
/// </summary>
/// <param name="top"></param>
/// <param name="bottom"></param>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
internal static Rectangle FromCoordinates(float top, float bottom, float left, float right)
public static Rectangle FromCoordinates(float top, float bottom, float left, float right)
{
return new Rectangle(
left,
Expand All @@ -88,6 +83,12 @@ internal static Rectangle FromCoordinates(float top, float bottom, float left, f
);
}

/// <summary>
/// Constructor for a rectangle from a set of coordinates.
/// </summary>
public static Rectangle FromCoordinates(Vector2 topLeft, Vector2 bottomRight) =>
FromCoordinates(top: topLeft.Y, bottom: bottomRight.Y, left: topLeft.X, right: bottomRight.X);

public static implicit operator Rectangle(IntRectangle p) => new(p.X, p.Y, p.Width, p.Height);

public Rectangle AddPosition(Vector2 position) => new Rectangle(X + Calculator.RoundToInt(position.X), Y + Calculator.RoundToInt(position.Y), Width, Height);
Expand Down

0 comments on commit 41b92c1

Please sign in to comment.