Skip to content

Commit

Permalink
support save/load drawingTargets' render order and visible
Browse files Browse the repository at this point in the history
  • Loading branch information
MikiraSora committed Oct 27, 2024
1 parent eb0958c commit c4ea81d
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 143 deletions.
3 changes: 3 additions & 0 deletions OngekiFumenEditor/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@
<setting name="LimitFPS" serializeAs="String">
<value>-1</value>
</setting>
<setting name="RenderTargetOrderVisibleMap" serializeAs="String">
<value />
</setting>
</OngekiFumenEditor.Properties.EditorGlobalSetting>
<OngekiFumenEditor.Properties.AudioPlayerToolViewerSetting>
<setting name="ResampleSize" serializeAs="String">
Expand Down
10 changes: 8 additions & 2 deletions OngekiFumenEditor/Kernel/KeyBinding/DefaultKeyBindingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ private class Config

private Dictionary<string, KeyBindingDefinition> definitionMap = new();

private JsonSerializerOptions serializerOptions = new JsonSerializerOptions()
{
WriteIndented = true,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
};

[ImportingConstructor]
public DefaultKeyBindingManager([ImportMany] KeyBindingDefinition[] definations)
{
Expand All @@ -42,7 +48,7 @@ public DefaultKeyBindingManager([ImportMany] KeyBindingDefinition[] definations)

public void SaveConfig()
{
var json = JsonSerializer.Serialize(new Config() { KeyBindings = definitionMap.ToDictionary(x => x.Key, x => KeyBindingDefinition.FormatToExpression(x.Value.Key, x.Value.Modifiers)) });
var json = JsonSerializer.Serialize(new Config() { KeyBindings = definitionMap.ToDictionary(x => x.Key, x => KeyBindingDefinition.FormatToExpression(x.Value.Key, x.Value.Modifiers)) }, serializerOptions);
File.WriteAllText(jsonConfigFilePath, json);

Log.LogInfo($"Saved.");
Expand Down Expand Up @@ -121,7 +127,7 @@ private static ModifierKeys GetActualModifiers(Key key, ModifierKeys modifiers)

public void ChangeKeyBinding(KeyBindingDefinition definition, Key newKey, ModifierKeys newModifier)
{
Log.LogInfo($"[{definition.Key}] {KeyBindingDefinition.FormatToExpression(definition.Key, definition.Modifiers)} --> {KeyBindingDefinition.FormatToExpression(newKey, newModifier)}");
Log.LogInfo($"[{definition.Name}] {KeyBindingDefinition.FormatToExpression(definition.Key, definition.Modifiers)} --> {KeyBindingDefinition.FormatToExpression(newKey, newModifier)}");

definition.Key = newKey;
definition.Modifiers = newModifier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using Gemini.Framework.Services;
using OngekiFumenEditor.Kernel.Graphics;
using OngekiFumenEditor.Modules.FumenVisualEditor.Graphics.Drawing;
using OngekiFumenEditor.Modules.FumenVisualEditor.Kernel;
using OngekiFumenEditor.Modules.FumenVisualEditor.ViewModels;
using OngekiFumenEditor.Properties;
using OngekiFumenEditor.Utils;
using System;
Expand All @@ -15,145 +17,150 @@

namespace OngekiFumenEditor.Modules.FumenEditorRenderControlViewer.ViewModels
{
[Export(typeof(IFumenEditorRenderControlViewer))]
public class FumenEditorRenderControlViewerViewModel : Tool, IFumenEditorRenderControlViewer
{
private ListViewDragDropManager<ControlItem> listDragManager;

public class ControlItem : PropertyChangedBase
{
public ControlItem(IFumenEditorDrawingTarget target)
{
this.target = target;
Name = target.GetType().Name.TrimEnd("DrawingTarget").TrimEnd("DrawTarget");
}

public string Name { get; init; }
private readonly IFumenEditorDrawingTarget target;

public IFumenEditorDrawingTarget Target => target;

public bool IsDesignEnable
{
get { return target.Visible.HasFlag(DrawingVisible.Design); }
set
{
if (value)
target.Visible |= DrawingVisible.Design;
else
target.Visible &= ~DrawingVisible.Design;
NotifyOfPropertyChange(() => IsDesignEnable);
}
}

public bool IsPreviewEnable
{
get { return target.Visible.HasFlag(DrawingVisible.Preview); }
set
{
if (value)
target.Visible |= DrawingVisible.Preview;
else
target.Visible &= ~DrawingVisible.Preview;
NotifyOfPropertyChange(() => IsPreviewEnable);
}
}

public int RenderOrder
{
get { return target.CurrentRenderOrder; }
set
{
target.CurrentRenderOrder = value;
NotifyOfPropertyChange(() => RenderOrder);
}
}

public override string ToString() => $"[{target.Visible}] : {Name}";
}

public override PaneLocation PreferredLocation => PaneLocation.Right;

public ObservableCollection<ControlItem> ControlItems { get; } = new ObservableCollection<ControlItem>();

public FumenEditorRenderControlViewerViewModel()
{
DisplayName = Resources.FumenEditorRenderControlViewer;
RebuildItems(false);
}

private async void RebuildItems(bool sortByDefault)
{
ControlItems.Clear();

await IoC.Get<IDrawingManager>().WaitForGraphicsInitializationDone();
var targets = IoC.GetAll<IFumenEditorDrawingTarget>().OrderBy(x => sortByDefault ? x.DefaultRenderOrder : x.CurrentRenderOrder).ToArray();
ControlItems.AddRange(targets.Select(x => new ControlItem(x)));

UpdateRenderOrder();
}

private void UpdateRenderOrder()
{
for (int i = 0; i < ControlItems.Count; i++)
ControlItems[i].RenderOrder = i;
}

public void ResetDefault()
{
RebuildItems(true);
for (int i = 0; i < ControlItems.Count; i++)
{
ControlItems[i].Target.Visible = ControlItems[i].Target.DefaultVisible;
ControlItems[i].Refresh();
}
}

public void OnListLoaded(FrameworkElement list)
{
listDragManager = new ListViewDragDropManager<ControlItem>(list as ListView);
listDragManager.ShowDragAdorner = true;
listDragManager.DragAdornerOpacity = 0.75f;

listDragManager.ProcessDrop += ListDragManager_ProcessDrop;

Log.LogDebug($"ListViewDragDropManager created.");
}

private void ListDragManager_ProcessDrop(object sender, ProcessDropEventArgs<ControlItem> e)
{
// This shows how to customize the behavior of a drop.
// Here we perform a swap, instead of just moving the dropped item.

int higherIdx = Math.Max(e.OldIndex, e.NewIndex);
int lowerIdx = Math.Min(e.OldIndex, e.NewIndex);

if (lowerIdx < 0)
{
// The item came from the lower ListView
// so just insert it.
e.ItemsSource.Insert(higherIdx, e.DataItem);
}
else
{
// null values will cause an error when calling Move.
// It looks like a bug in ObservableCollection to me.
if (e.ItemsSource[lowerIdx] == null ||
e.ItemsSource[higherIdx] == null)
return;

// The item came from the ListView into which
// it was dropped, so swap it with the item
// at the target index.
e.ItemsSource.Move(lowerIdx, higherIdx);
e.ItemsSource.Move(higherIdx - 1, lowerIdx);
}

UpdateRenderOrder();

// Set this to 'Move' so that the OnListViewDrop knows to
// remove the item from the other ListView.
e.Effects = DragDropEffects.Move;
}
}
[Export(typeof(IFumenEditorRenderControlViewer))]
public class FumenEditorRenderControlViewerViewModel : Tool, IFumenEditorRenderControlViewer
{
private ListViewDragDropManager<ControlItem> listDragManager;

public class ControlItem : PropertyChangedBase
{
public ControlItem(IFumenEditorDrawingTarget target)
{
this.target = target;
Name = target.GetType().Name.TrimEnd("DrawingTarget").TrimEnd("DrawTarget");
}

public string Name { get; init; }
private readonly IFumenEditorDrawingTarget target;

public IFumenEditorDrawingTarget Target => target;

public bool IsDesignEnable
{
get { return target.Visible.HasFlag(DrawingVisible.Design); }
set
{
if (value)
target.Visible |= DrawingVisible.Design;
else
target.Visible &= ~DrawingVisible.Design;
NotifyOfPropertyChange(() => IsDesignEnable);
}
}

public bool IsPreviewEnable
{
get { return target.Visible.HasFlag(DrawingVisible.Preview); }
set
{
if (value)
target.Visible |= DrawingVisible.Preview;
else
target.Visible &= ~DrawingVisible.Preview;
NotifyOfPropertyChange(() => IsPreviewEnable);
}
}

public int RenderOrder
{
get { return target.CurrentRenderOrder; }
set
{
target.CurrentRenderOrder = value;
NotifyOfPropertyChange(() => RenderOrder);
}
}

public override string ToString() => $"[{target.Visible}] : {Name}";
}

public override PaneLocation PreferredLocation => PaneLocation.Right;

public ObservableCollection<ControlItem> ControlItems { get; } = new ObservableCollection<ControlItem>();

public FumenEditorRenderControlViewerViewModel()
{
DisplayName = Resources.FumenEditorRenderControlViewer;
RebuildItems(false);
}

private async void RebuildItems(bool sortByDefault)
{
ControlItems.Clear();

await IoC.Get<IDrawingManager>().WaitForGraphicsInitializationDone();
var targets = IoC.GetAll<IFumenEditorDrawingTarget>().OrderBy(x => sortByDefault ? x.DefaultRenderOrder : x.CurrentRenderOrder).ToArray();
ControlItems.AddRange(targets.Select(x => new ControlItem(x)));

UpdateRenderOrder();
}

private void UpdateRenderOrder()
{
for (int i = 0; i < ControlItems.Count; i++)
ControlItems[i].RenderOrder = i;
}

public void ResetDefault()
{
RebuildItems(true);
for (int i = 0; i < ControlItems.Count; i++)
{
ControlItems[i].Target.Visible = ControlItems[i].Target.DefaultVisible;
ControlItems[i].Refresh();
}
}

public void Save()
{
IoC.Get<IEditorDocumentManager>().CurrentActivatedEditor?.SaveRenderOrderVisible();
}

public void OnListLoaded(FrameworkElement list)
{
listDragManager = new ListViewDragDropManager<ControlItem>(list as ListView);
listDragManager.ShowDragAdorner = true;
listDragManager.DragAdornerOpacity = 0.75f;

listDragManager.ProcessDrop += ListDragManager_ProcessDrop;

Log.LogDebug($"ListViewDragDropManager created.");
}

private void ListDragManager_ProcessDrop(object sender, ProcessDropEventArgs<ControlItem> e)
{
// This shows how to customize the behavior of a drop.
// Here we perform a swap, instead of just moving the dropped item.

int higherIdx = Math.Max(e.OldIndex, e.NewIndex);
int lowerIdx = Math.Min(e.OldIndex, e.NewIndex);

if (lowerIdx < 0)
{
// The item came from the lower ListView
// so just insert it.
e.ItemsSource.Insert(higherIdx, e.DataItem);
}
else
{
// null values will cause an error when calling Move.
// It looks like a bug in ObservableCollection to me.
if (e.ItemsSource[lowerIdx] == null ||
e.ItemsSource[higherIdx] == null)
return;

// The item came from the ListView into which
// it was dropped, so swap it with the item
// at the target index.
e.ItemsSource.Move(lowerIdx, higherIdx);
e.ItemsSource.Move(higherIdx - 1, lowerIdx);
}

UpdateRenderOrder();

// Set this to 'Move' so that the OnListViewDrop knows to
// remove the item from the other ListView.
e.Effects = DragDropEffects.Move;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using OngekiFumenEditor.Modules.FumenVisualEditor.Graphics.Drawing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OngekiFumenEditor.Modules.FumenVisualEditor.Base
{
public class RenderTargetOrderVisible
{
public int Order { get; set; }
public DrawingVisible Visible { get; set; }
}
}
Loading

0 comments on commit c4ea81d

Please sign in to comment.