* Add the instrument to the MIDI channel selector * Reviews Adds support for chained masters Makes the channel UI update on its own when the midi changes (Works with bands too!) * add to admin logs and limit track count * Limit track names by length too * remove left over comment * Requested changes * Reviews
154 lines
5.2 KiB
C#
154 lines
5.2 KiB
C#
using Content.Shared.Instruments;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.CustomControls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.Audio.Midi;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Client.Instruments.UI;
|
|
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class ChannelsMenu : DefaultWindow
|
|
{
|
|
[Dependency] private readonly IEntityManager _entityManager = null!;
|
|
|
|
private readonly InstrumentBoundUserInterface _owner;
|
|
|
|
public ChannelsMenu(InstrumentBoundUserInterface owner) : base()
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
IoCManager.InjectDependencies(this);
|
|
_owner = owner;
|
|
|
|
ChannelList.OnItemSelected += OnItemSelected;
|
|
ChannelList.OnItemDeselected += OnItemDeselected;
|
|
AllButton.OnPressed += OnAllPressed;
|
|
ClearButton.OnPressed += OnClearPressed;
|
|
DisplayTrackNames.OnPressed += OnDisplayTrackNamesPressed;
|
|
}
|
|
|
|
protected override void EnteredTree()
|
|
{
|
|
base.EnteredTree();
|
|
|
|
_owner.Instruments.OnChannelsUpdated += UpdateChannelList;
|
|
}
|
|
|
|
private void OnDisplayTrackNamesPressed(BaseButton.ButtonEventArgs obj)
|
|
{
|
|
DisplayTrackNames.SetClickPressed(!DisplayTrackNames.Pressed);
|
|
Populate();
|
|
}
|
|
|
|
private void UpdateChannelList()
|
|
{
|
|
Populate(); // This is kind of in-efficent because we don't filter for which instrument updated its channels, but idc
|
|
}
|
|
|
|
protected override void ExitedTree()
|
|
{
|
|
base.ExitedTree();
|
|
|
|
_owner.Instruments.OnChannelsUpdated -= UpdateChannelList;
|
|
}
|
|
|
|
private void OnItemSelected(ItemList.ItemListSelectedEventArgs args)
|
|
{
|
|
_owner.Instruments.SetFilteredChannel(_owner.Owner, (int)ChannelList[args.ItemIndex].Metadata!, false);
|
|
}
|
|
|
|
private void OnItemDeselected(ItemList.ItemListDeselectedEventArgs args)
|
|
{
|
|
_owner.Instruments.SetFilteredChannel(_owner.Owner, (int)ChannelList[args.ItemIndex].Metadata!, true);
|
|
}
|
|
|
|
private void OnAllPressed(BaseButton.ButtonEventArgs obj)
|
|
{
|
|
foreach (var item in ChannelList)
|
|
{
|
|
// TODO: Make this efficient jfc
|
|
item.Selected = true;
|
|
}
|
|
}
|
|
|
|
private void OnClearPressed(BaseButton.ButtonEventArgs obj)
|
|
{
|
|
foreach (var item in ChannelList)
|
|
{
|
|
// TODO: Make this efficient jfc
|
|
item.Selected = false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Walks up the tree of instrument masters to find the truest master of them all.
|
|
/// </summary>
|
|
private ActiveInstrumentComponent ResolveActiveInstrument(InstrumentComponent? comp)
|
|
{
|
|
comp ??= _entityManager.GetComponent<InstrumentComponent>(_owner.Owner);
|
|
|
|
var instrument = new Entity<InstrumentComponent>(_owner.Owner, comp);
|
|
|
|
while (true)
|
|
{
|
|
if (instrument.Comp.Master == null)
|
|
break;
|
|
|
|
instrument = new Entity<InstrumentComponent>((EntityUid)instrument.Comp.Master,
|
|
_entityManager.GetComponent<InstrumentComponent>((EntityUid)instrument.Comp.Master));
|
|
}
|
|
|
|
return _entityManager.GetComponent<ActiveInstrumentComponent>(instrument.Owner);
|
|
}
|
|
|
|
public void Populate()
|
|
{
|
|
ChannelList.Clear();
|
|
var instrument = _entityManager.GetComponent<InstrumentComponent>(_owner.Owner);
|
|
var activeInstrument = ResolveActiveInstrument(instrument);
|
|
|
|
for (int i = 0; i < RobustMidiEvent.MaxChannels; i++)
|
|
{
|
|
var label = _owner.Loc.GetString("instrument-component-channel-name",
|
|
("number", i));
|
|
if (activeInstrument != null
|
|
&& activeInstrument.Tracks.TryGetValue(i, out var resolvedMidiChannel)
|
|
&& resolvedMidiChannel != null)
|
|
{
|
|
if (DisplayTrackNames.Pressed)
|
|
{
|
|
label = resolvedMidiChannel switch
|
|
{
|
|
{ TrackName: not null, InstrumentName: not null } =>
|
|
Loc.GetString("instruments-component-channels-multi",
|
|
("channel", i),
|
|
("name", resolvedMidiChannel.TrackName),
|
|
("other", resolvedMidiChannel.InstrumentName)),
|
|
{ TrackName: not null } =>
|
|
Loc.GetString("instruments-component-channels-single",
|
|
("channel", i),
|
|
("name", resolvedMidiChannel.TrackName)),
|
|
_ => label,
|
|
};
|
|
}
|
|
else
|
|
{
|
|
label = resolvedMidiChannel switch
|
|
{
|
|
{ ProgramName: not null } =>
|
|
Loc.GetString("instruments-component-channels-single",
|
|
("channel", i),
|
|
("name", resolvedMidiChannel.ProgramName)),
|
|
_ => label,
|
|
};
|
|
}
|
|
}
|
|
|
|
var item = ChannelList.AddItem(label, null, true, i);
|
|
|
|
item.Selected = !instrument?.FilteredChannels[i] ?? false;
|
|
}
|
|
}
|
|
}
|