Skip to content

Commit

Permalink
More changes to sprite editor.
Browse files Browse the repository at this point in the history
  • Loading branch information
isadorasophia committed Dec 17, 2023
1 parent 5f188d1 commit 594f71a
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 49 deletions.
159 changes: 112 additions & 47 deletions src/Murder.Editor/CustomEditors/SpriteEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Murder.Editor.Assets;
using Murder.Editor.Attributes;
using Murder.Editor.CustomFields;
using Murder.Editor.EditorCore;
using Murder.Editor.ImGuiExtended;
using Murder.Editor.Stages;
using Murder.Editor.Systems;
Expand Down Expand Up @@ -115,14 +116,10 @@ public override void DrawEditor()

if (ImGui.BeginChild("Viewport", new Vector2(-1, _viewportSize)))
{
if (ActiveEditors.ContainsKey(_sprite.Guid))
{
windowSize = ImGui.GetContentRegionAvail();
Vector2 origin = ImGui.GetItemRectMin();
float length = windowSize.X / 3f;
windowSize = ImGui.GetContentRegionAvail();
Vector2 origin = ImGui.GetItemRectMin();

stage.Draw();
}
stage.Draw();
}

ImGui.EndChild();
Expand All @@ -134,15 +131,6 @@ public override void DrawEditor()

ImGui.TextColored(Game.Profile.Theme.HighAccent, "\uf0e0 Animation Messages");

ImGui.InputInt($"##frame {_sprite.Guid}", ref _value);

ImGui.InputTextWithHint($"##input {_sprite.Guid}", "Message name...", ref _message, 256);

if (ImGui.Button("Add message!"))
{
AddMessage(info.SelectedAnimation, _value, _message);
}

DrawMessages(info);
}

Expand Down Expand Up @@ -230,7 +218,6 @@ private void SelectAnimation(SpriteInformation info, string animation)
new AnimationOverloadComponent(animation, loop: true, ignoreFacing: true, startTime: info.Hook.Time));
}

private int _value = 0;
private string _message = string.Empty;

private void DrawMessages(SpriteInformation info)
Expand Down Expand Up @@ -261,7 +248,7 @@ private void DrawMessages(SpriteInformation info)

ImGui.SameLine();

ImGuiHelpers.SelectedButton($"Frame {i}");
ImGuiHelpers.SelectedButton($"{i}");

ImGui.TableNextColumn();
ImGui.Text(message);
Expand All @@ -283,6 +270,9 @@ private void DrawTimeline(SpriteInformation info)
{
GameLogger.Verify(_sprite is not null);

int targetAnimationFrame = 0;
string selectedMessage = string.Empty;

if (ImGui.BeginChild("Timeline Area"))
{
if (_sprite.Animations.TryGetValue(info.SelectedAnimation, out Animation selectedAnimation))
Expand All @@ -298,29 +288,8 @@ private void DrawTimeline(SpriteInformation info)

ImGui.SameLine();

StringBuilder text = new();
if (string.IsNullOrEmpty(info.SelectedAnimation))
{
text.Append("Default animation");
}
else
{
text.Append($"\"{info.SelectedAnimation}\"");
}

if (selectedAnimation.Events.Count == 0)
{
text.Append(" | 0 events");
}
else
{
text.Append($" | {selectedAnimation.Events.Count} event{(selectedAnimation.Events.Count > 1 ? "s" : "")}");
}

text.Append($" | {selectedAnimation.AnimationDuration}s");
DrawHeader(info, selectedAnimation);

ImGui.TextColored(Game.Profile.Theme.Faded, text.ToString());

if (ImGui.BeginChild("Timeline"))
{
Vector2 position = ImGui.GetItemRectMin();
Expand All @@ -339,7 +308,7 @@ private void DrawTimeline(SpriteInformation info)

float currentPosition = padding;

int animationFrame = selectedAnimation.Evaluate(info.AnimationProgress * selectedAnimation.AnimationDuration, false).InternalFrame;
targetAnimationFrame = selectedAnimation.Evaluate(info.AnimationProgress * selectedAnimation.AnimationDuration, false).InternalFrame;

for (int i = 0; i < selectedAnimation.FrameCount; i++)
{
Expand All @@ -354,28 +323,32 @@ private void DrawTimeline(SpriteInformation info)

drawList.AddLine(framePosition + new Vector2(width, 0), framePosition + new Vector2(width, frameSize.Y), frameColor, 2);

if (animationFrame == i)
if (targetAnimationFrame == i)
{
drawList.AddRectFilled(framePosition + new Vector2(padding, 0), framePosition + frameSize, frameColor, 8);
}

if (selectedAnimation.Events.TryGetValue(i, out var @event))
{
selectedMessage = @event;

drawList.AddRect(framePosition + new Vector2(padding, 0), framePosition + frameSize, frameKeyColor, 8);
if (frameRectangle.Contains(ImGui.GetMousePos()))

if (frameRectangle.Contains(ImGui.GetMousePos()) && !info.Hook.IsPopupOpen)
{
ImGui.BeginTooltip();
ImGui.Text($"{i}\n{@event}\n{frameDuration}ms");
ImGui.Text($"{i}\n\"{@event}\"\n{frameDuration}ms");
ImGui.EndTooltip();
}

if (frameRectangle.Width > @event.Length * 8)
{
drawList.AddText(framePosition + new Vector2(padding * 2, padding * 2), frameKeyColor, @event);
}
}
else
{
if (frameRectangle.Contains(ImGui.GetMousePos()))
if (frameRectangle.Contains(ImGui.GetMousePos()) && !info.Hook.IsPopupOpen)
{
ImGui.BeginTooltip();
ImGui.Text($"{i}\n{frameDuration}ms");
Expand All @@ -386,9 +359,9 @@ private void DrawTimeline(SpriteInformation info)

float rate = (info.Hook.Time % selectedAnimation.AnimationDuration) / selectedAnimation.AnimationDuration;

if (new Rectangle(position, area).Contains(ImGui.GetMousePos()) && ImGui.IsMouseDown(ImGuiMouseButton.Left))
if (new Rectangle(position, area).Contains(ImGui.GetMousePos()) && ImGui.IsMouseDown(ImGuiMouseButton.Left) && !info.Hook.IsPopupOpen)
{
float mouseX = ImGui.GetMousePos().X - position.X;
float mouseX = ImGui.GetMousePos().X - position.X - 10 /* cursor offset...? */;

info.AnimationProgress = Calculator.Clamp01(mouseX / (area.X - padding * 2));
rate = info.AnimationProgress;
Expand All @@ -407,11 +380,97 @@ private void DrawTimeline(SpriteInformation info)
}

ImGui.EndChild();

DrawAddMessageOnRightClick(info, targetAnimationFrame, selectedMessage);
}

ImGui.EndChild();
}

private void DrawAddMessageOnRightClick(SpriteInformation info, int frame, string message)
{
bool open = false;
if (ImGui.BeginPopupContextItem())
{
info.Hook.IsPopupOpen = true;

string text = string.IsNullOrEmpty(message) ? "Add message..." : "Rename";
if (ImGui.Selectable(text))
{
open = true;
}

if (!string.IsNullOrEmpty(message) && ImGui.Selectable("Delete"))
{
DeleteMessage(info.SelectedAnimation, frame);
}

ImGui.EndPopup();
}
else
{
info.Hook.IsPopupOpen = false;
}

if (open)
{
ImGui.OpenPopup("add_message_to_frame");
_message = message;
}

if (ImGui.BeginPopup("add_message_to_frame"))
{
ImGui.PushItemWidth(170);
info.Hook.IsPopupOpen = true;

ImGui.Text($"Fire message at frame {frame}:");
ImGui.InputText("##add_new_message_input", ref _message, 128);

if (string.IsNullOrEmpty(_message))
{
ImGuiHelpers.SelectedButton("Add");
}
else if (ImGui.Button("Add"))
{
AddMessage(info.SelectedAnimation, frame, _message);

_message = string.Empty;
info.Hook.IsPopupOpen = false;

ImGui.CloseCurrentPopup();
}

ImGui.PopItemWidth();
ImGui.EndPopup();
}
}

private void DrawHeader(SpriteInformation info, Animation animation)
{
StringBuilder text = new();
if (string.IsNullOrEmpty(info.SelectedAnimation))
{
text.Append("Default animation");
}
else
{
text.Append($"\"{info.SelectedAnimation}\"");
}

if (animation.Events.Count == 0)
{
text.Append(" | 0 events");
}
else
{
text.Append($" | {animation.Events.Count} event{(animation.Events.Count > 1 ? "s" : "")}");
}

text.Append($" | {animation.AnimationDuration}s");

ImGui.TextColored(Game.Profile.Theme.Faded, text.ToString());
}

public override void CloseEditor(Guid target)
{
if (ActiveEditors.TryGetValue(target, out SpriteInformation? info))
Expand Down Expand Up @@ -439,8 +498,14 @@ protected record SpriteInformation(Stage Stage)
/// </summary>
public float AnimationProgress = 0;

/// <summary>
/// Shortcut for the timeline editor hook.
/// </summary>
public TimelineEditorHook Hook => (TimelineEditorHook)Stage.EditorHook;

/// <summary>
/// Field "borrowed" for assigning <see cref="SoundTests"/>.
/// </summary>
public SoundEventId SoundTest = new();

[Tooltip("This will create a sound to test in this editor. The actual sound must be added to the entity!")]
Expand Down
5 changes: 4 additions & 1 deletion src/Murder.Editor/CustomEditors/WorldAssetEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ protected override void InitializeStage(Stage stage, Guid guid)

public override void UpdateEditor()
{
GameLogger.Verify(Stages.ContainsKey(_asset!.Guid));
if (_asset is null || !Stages.ContainsKey(_asset!.Guid))
{
return;
}

Stage currentStage = Stages[_asset.Guid];
currentStage.Update();
Expand Down
5 changes: 5 additions & 0 deletions src/Murder.Editor/Stage/Stage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,5 +220,10 @@ internal void ResetCamera()
_renderContext.Camera.Zoom = 1;
_renderContext.Camera.Position = Vector2.Zero;
}

internal void CenterCamera(Vector2 size)
{
_renderContext.Camera.Position -= size / 2f;
}
}
}
2 changes: 1 addition & 1 deletion src/Murder.Editor/Systems/EntitiesPlacerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private bool DrawCreateEmptyEntity(World world, EditorHook hook)
/* name */ null);
}

if (ImGui.Selectable("Add unique prop"))
if (ImGui.Selectable("Add unique prop..."))
{
Point cursorWorldPosition = hook.CursorWorldPosition;
string? targetGroup = EditorTileServices.FindTargetGroup(world, hook, cursorWorldPosition);
Expand Down

0 comments on commit 594f71a

Please sign in to comment.