Skip to content

Commit

Permalink
add drag & multiselect
Browse files Browse the repository at this point in the history
  • Loading branch information
CharlesGameDev committed Apr 9, 2024
1 parent 64b11c9 commit d0386e3
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 66 deletions.
13 changes: 1 addition & 12 deletions Fushigi/course/Course.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@

using Silk.NET.Windowing;
using Silk.NET.OpenGL;
using ImGuiNET;
using Fushigi.util;
using Fushigi.windowing;
using Fushigi.util;
using Fushigi.Byml;
using Fushigi.Byml.Writer;
using Fushigi.Byml.Writer.Primitives;
using Fushigi;
using Fushigi.course;
using Fushigi.rstb;
using Fushigi.ui.widgets;
using System.IO;

namespace Fushigi.course
{
Expand Down
32 changes: 24 additions & 8 deletions Fushigi/course/CourseActor.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
using Fushigi.Byml;
using Fushigi.Byml.Serializer;
using Fushigi.Byml.Writer;
using Fushigi.param;
using Fushigi.util;
using Silk.NET.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fushigi.course
{
Expand Down Expand Up @@ -224,6 +217,29 @@ public BymlHashTable BuildNode(CourseLinkHolder linkHolder)
return table;
}

public CourseActor Clone()
{
CourseActor cloned = new(mPackName, mAreaHash, mLayer)
{
mPackName = mPackName,
mName = mName + "Copy",
mLayer = mLayer,
mWonderView = mWonderView,
wonderVisible = wonderVisible,
mStartingTrans = mStartingTrans,
mTranslation = mTranslation,
mRotation = mRotation
};
cloned.mStartingTrans = mStartingTrans;
cloned.mAreaHash = mAreaHash;
cloned.mHash = (ulong)(new Random().NextDouble() * ulong.MaxValue);
cloned.mActorParameters = mActorParameters;
cloned.mSystemParameters = mSystemParameters;
cloned.mActorPack = mActorPack;

return cloned;
}

public string mPackName;
public string mName;
public string mLayer;
Expand Down
5 changes: 0 additions & 5 deletions Fushigi/rstb/RSTB.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
using Fushigi.util;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Fushigi.rstb
{
Expand Down
8 changes: 1 addition & 7 deletions Fushigi/ui/undo/AddDeleteUndo.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fushigi.ui.undo
namespace Fushigi.ui.undo
{
public static class ListUndoExtensions
{
Expand Down
8 changes: 1 addition & 7 deletions Fushigi/ui/undo/IRevertable.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fushigi.ui
namespace Fushigi.ui
{
public interface IRevertable
{
Expand Down
6 changes: 1 addition & 5 deletions Fushigi/ui/undo/UndoRedo.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Fushigi.ui
namespace Fushigi.ui
{
public class UndoHandler
{
Expand Down
4 changes: 0 additions & 4 deletions Fushigi/ui/widgets/CourseScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@
using ImGuiNET;
using Silk.NET.OpenGL;
using System.Collections.Immutable;
using System.Drawing;
using System.Diagnostics;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Fushigi.rstb;
using Fushigi.course.distance_view;
using Fushigi.ui.helpers;
using Fasterflect;
using System.Text.RegularExpressions;
Expand Down
129 changes: 117 additions & 12 deletions Fushigi/ui/widgets/LevelViewport.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Fasterflect;
using Fushigi.actor_pack.components;
using Fushigi.Bfres;
using Fushigi.Byml.Serializer;
Expand All @@ -7,20 +8,17 @@
using Fushigi.gl.Bfres;
using Fushigi.gl.Bfres.AreaData;
using Fushigi.param;
using Fushigi.ui.undo;
using Fushigi.util;
using ImGuiNET;
using Silk.NET.OpenGL;
using System;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Dynamic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Xml;
using static Fushigi.course.CourseUnit;
using Fushigi.ui.undo;
using Vector3 = System.Numerics.Vector3;
using Fasterflect;

namespace Fushigi.ui.widgets
{
Expand Down Expand Up @@ -69,6 +67,8 @@ enum KeyboardModifier

internal class LevelViewport(CourseArea area, GL gl, CourseAreaScene areaScene)
{
public static object?[] CopiedObjects = [];

public void PreventFurtherRendering() => mIsNoMoreRendering = true;
private bool mIsNoMoreRendering = false;

Expand Down Expand Up @@ -110,8 +110,14 @@ internal class LevelViewport(CourseArea area, GL gl, CourseAreaScene areaScene)
//TODO make this an ISceneObject? as soon as there's a SceneObj class for each course object
private object? mHoveredObject;

Vector2? mMultiSelectStartPos;
Vector2? mMultiSelectCurrentPos;
bool mMultiSelecting = false;

public static uint GridColor = 0x77_FF_FF_FF;
public static float GridLineThickness = 1.5f;
public static uint MultiSelectBoxColor = 0x90_00_00_FF;
public static float MultiSelectBoxThickness = 3f;

private (string message, Predicate<object?> predicate,
TaskCompletionSource<(object? picked, KeyboardModifier modifiers)> promise)?
Expand Down Expand Up @@ -706,14 +712,65 @@ public void Draw(Vector2 size, double deltaSeconds, IDictionary<string, bool> la
mEditContext.Redo();
}

CourseActor[] selectedActors = areaScene.EditContext.GetSelectedObjects<CourseActor>().ToArray();

if (selectedActors.Length != 0 &&
ImGui.IsKeyPressed(ImGuiKey.C) && modifiers == KeyboardModifier.CtrlCmd)
{
CopiedObjects = new CourseActor[selectedActors.Length];
for (int i = 0; i < CopiedObjects.Length; i++)
CopiedObjects[i] = selectedActors[i].Clone();
}
if (CopiedObjects.Length != 0 &&
ImGui.IsKeyPressed(ImGuiKey.V) && modifiers == KeyboardModifier.CtrlCmd)
{
DoPaste();
}

if (ImGui.IsWindowFocused())
InteractionWithFocus(modifiers);

ImGui.PopClipRect();
}

private async Task DoPaste()
{
if (CopiedObjects.Length == 0) return;

Vector3? _pos;
KeyboardModifier modifier;
CourseActor[]? actors = CopiedObjects as CourseActor[];
if (actors == null) return;

string msg;
if (actors.Length == 1)
msg = $"Placing actor {actors[0].mPackName}";
else
msg = $"Placing {actors.Length} actors";
msg += " -- Hold SHIFT to place multiple";

(_pos, modifier) = await PickPosition(msg, actors[0].mLayer);
if (_pos == null) return;

foreach (var actor in actors)
{
Vector3 pos = _pos.Value;
pos = new Vector3((float)Math.Round(pos.X, 0), (float)Math.Round(pos.Y, 0), actor.mTranslation.Z);

CourseActor newActor = actor.Clone();
newActor.mTranslation = pos;

areaScene.EditContext.AddActor(newActor);
}

areaScene.EditContext.Select(actors);

if (modifier == KeyboardModifier.Shift)
{
DoPaste();
}
}

void InteractionWithFocus(KeyboardModifier modifiers)
{
if (IsViewportHovered &&
Expand Down Expand Up @@ -762,9 +819,46 @@ void InteractionWithFocus(KeyboardModifier modifiers)

if (ImGui.IsMouseDragging(ImGuiMouseButton.Left) && !isPanGesture)
{
if (mEditContext.IsAnySelected<CourseActor>())
if (mMultiSelectStartPos != null)
{
foreach(CourseActor actor in mEditContext.GetSelectedObjects<CourseActor>())
mMultiSelectCurrentPos = ImGui.GetMousePos();
mMultiSelecting = true;

Vector3 startPosWorldStart = ScreenToWorld(mMultiSelectStartPos.Value);
Vector3 currentPosWorldStart = ScreenToWorld(mMultiSelectCurrentPos.Value);

Vector3 startPosWorld = startPosWorldStart;
Vector3 currentPosWorld = currentPosWorldStart;

if (currentPosWorldStart.X < startPosWorldStart.X)
{
currentPosWorld.X = startPosWorldStart.X;
startPosWorld.X = currentPosWorldStart.X;
}
if (currentPosWorldStart.Y < startPosWorldStart.Y)
{
currentPosWorld.Y = startPosWorldStart.Y;
startPosWorld.Y = currentPosWorldStart.Y;
}

CourseActor[] actors = [.. mArea.GetActors()];
foreach (var actor in actors)
{
float actorX = actor.mTranslation.X;
float actorY = actor.mTranslation.Y;

if (actorX > startPosWorld.X && actorX < currentPosWorld.X && actorY > startPosWorld.Y && actorY < currentPosWorld.Y)
{
mEditContext.Select(actor);
} else
{
mEditContext.Deselect(actor);
}
}
}
else if (!mMultiSelecting && mEditContext.IsAnySelected<CourseActor>())
{
foreach (CourseActor actor in mEditContext.GetSelectedObjects<CourseActor>())
{
Vector3 posVec = ScreenToWorld(ImGui.GetMousePos());
posVec -= ScreenToWorld(ImGui.GetIO().MouseClickedPos[0]) - actor.mStartingTrans;
Expand All @@ -782,7 +876,7 @@ void InteractionWithFocus(KeyboardModifier modifiers)
}
}
}
if (mEditContext.IsSingleObjectSelected(out CourseRail.CourseRailPoint? rail))
else if (!mMultiSelecting && mEditContext.IsSingleObjectSelected(out CourseRail.CourseRailPoint? rail))
{
Vector3 posVec = ScreenToWorld(ImGui.GetMousePos());

Expand All @@ -798,7 +892,7 @@ void InteractionWithFocus(KeyboardModifier modifiers)
rail.mTranslate = posVec;
}
}
if (mEditContext.IsSingleObjectSelected(out CourseRail.CourseRailPointControl? railCont))
else if (!mMultiSelecting && mEditContext.IsSingleObjectSelected(out CourseRail.CourseRailPointControl? railCont))
{
Vector3 posVec = ScreenToWorld(ImGui.GetMousePos());

Expand Down Expand Up @@ -839,11 +933,19 @@ void InteractionWithFocus(KeyboardModifier modifiers)
}
}

if (ImGui.IsMouseDown(0) && !isPanGesture)
dragRelease = ImGui.IsMouseDragging(0);
if (ImGui.IsMouseDown(0))
{
if (!ImGui.IsMouseDragging(0))
mMultiSelectStartPos = ImGui.GetMousePos();
if (!isPanGesture)
dragRelease = ImGui.IsMouseDragging(0);
}

if(ImGui.IsMouseReleased(0))
{
if (mMultiSelecting)
mMultiSelecting = false;

if(mHoveredObject != null &&
mHoveredObject is CourseActor &&
!dragRelease)
Expand Down Expand Up @@ -1158,6 +1260,9 @@ Vector2[] GetPoints()
}
}
}

if (mMultiSelecting && mMultiSelectStartPos != null && mMultiSelectCurrentPos != null)
mDrawList.AddRect(mMultiSelectStartPos.Value, mMultiSelectCurrentPos.Value, MultiSelectBoxColor, 2f, ImDrawFlags.RoundCornersAll, MultiSelectBoxThickness);
}

foreach (CourseActor actor in mArea.GetActors())
Expand Down
1 change: 0 additions & 1 deletion Fushigi/ui/widgets/Preferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Fushigi.ui.modal;
using Fushigi.util;
using ImGuiNET;
using Silk.NET.OpenGL;
using System.Numerics;

namespace Fushigi.ui.widgets
Expand Down
5 changes: 0 additions & 5 deletions Fushigi/ui/widgets/Tooltip.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using ImGuiNET;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fushigi.ui.widgets
{
Expand Down

0 comments on commit d0386e3

Please sign in to comment.