diff --git a/VRCOSC.Desktop/VRCOSC.Desktop.csproj b/VRCOSC.Desktop/VRCOSC.Desktop.csproj
index 151ee9c2..9e62a202 100644
--- a/VRCOSC.Desktop/VRCOSC.Desktop.csproj
+++ b/VRCOSC.Desktop/VRCOSC.Desktop.csproj
@@ -6,12 +6,12 @@
game.ico
app.manifest
0.0.0
- 2023.516.0
+ 2023.531.0
VRCOSC
VolcanicArts
VolcanicArts
enable
- 2023.516.0
+ 2023.531.0
diff --git a/VRCOSC.Desktop/VRCOSCGameDesktop.cs b/VRCOSC.Desktop/VRCOSCGameDesktop.cs
index 9ef622ce..aa191c21 100644
--- a/VRCOSC.Desktop/VRCOSCGameDesktop.cs
+++ b/VRCOSC.Desktop/VRCOSCGameDesktop.cs
@@ -4,12 +4,10 @@
using VRCOSC.Desktop.Updater;
using VRCOSC.Game;
using VRCOSC.Game.Graphics.Updater;
-using VRCOSC.Modules;
namespace VRCOSC.Desktop;
public partial class VRCOSCGameDesktop : VRCOSCGame
{
- protected override IVRCOSCSecrets GetSecrets() => new VRCOSCModuleSecrets();
protected override VRCOSCUpdateManager CreateUpdateManager() => new SquirrelUpdateManager();
}
diff --git a/VRCOSC.Game.Tests/VRCOSC.Game.Tests.csproj b/VRCOSC.Game.Tests/VRCOSC.Game.Tests.csproj
index 348067dd..5a63d763 100644
--- a/VRCOSC.Game.Tests/VRCOSC.Game.Tests.csproj
+++ b/VRCOSC.Game.Tests/VRCOSC.Game.Tests.csproj
@@ -1,4 +1,4 @@
-
+
WinExe
net6.0-windows10.0.22621.0
@@ -10,7 +10,7 @@
-
+
diff --git a/VRCOSC.Game/ChatBox/Clips/Clip.cs b/VRCOSC.Game/ChatBox/Clips/Clip.cs
index c7917b95..6b1c66d0 100644
--- a/VRCOSC.Game/ChatBox/Clips/Clip.cs
+++ b/VRCOSC.Game/ChatBox/Clips/Clip.cs
@@ -228,8 +228,12 @@ private string formatText(IProvidesFormat formatter)
if (!chatBoxManager.ModuleEnabledCache[clipVariable.Module]) return;
chatBoxManager.VariableValues.TryGetValue((clipVariable.Module, clipVariable.Lookup), out var variableValue);
-
returnText = returnText.Replace(clipVariable.DisplayableFormat, variableValue ?? string.Empty);
+
+ chatBoxManager.VariableValues.Where(pair => pair.Key.Item2.StartsWith($"{clipVariable.Lookup}_")).ForEach(pair =>
+ {
+ returnText = returnText.Replace(clipVariable.DisplayableFormatWithSuffix(pair.Key.Item2.Split('_').Last()), pair.Value);
+ });
});
return returnText;
@@ -268,8 +272,6 @@ private void removeStatesOfRemovedModules(NotifyCollectionChangedEventArgs e)
private void addStatesOfAddedModules(NotifyCollectionChangedEventArgs e)
{
- var checkDefaultState = !States.Any() && e.NewItems!.Count == 1;
-
foreach (string moduleName in e.NewItems!)
{
var currentStateCopy = States.Select(clipState => clipState.Copy()).ToList();
@@ -287,12 +289,6 @@ private void addStatesOfAddedModules(NotifyCollectionChangedEventArgs e)
States.AddRange(localCurrentStatesCopy);
States.Add(new ClipState(newStateMetadata));
}
-
- if (checkDefaultState)
- {
- var defaultState = GetStateFor(moduleName, @"default");
- if (defaultState is not null) defaultState.Enabled.Value = true;
- }
}
}
diff --git a/VRCOSC.Game/ChatBox/Clips/ClipVariable.cs b/VRCOSC.Game/ChatBox/Clips/ClipVariable.cs
index f0e6f71e..3a482e22 100644
--- a/VRCOSC.Game/ChatBox/Clips/ClipVariable.cs
+++ b/VRCOSC.Game/ChatBox/Clips/ClipVariable.cs
@@ -17,4 +17,5 @@ public class ClipVariableMetadata
public required string Format { get; init; }
public string DisplayableFormat => $"{variable_start_char}{Module.Replace("module", string.Empty)}.{Format}{variable_end_char}";
+ public string DisplayableFormatWithSuffix(string suffix) => $"{variable_start_char}{Module.Replace("module", string.Empty)}.{Format}_{suffix}{variable_end_char}";
}
diff --git a/VRCOSC.Game/ChatBox/Serialisation/V1/TimelineSerialiser.cs b/VRCOSC.Game/ChatBox/Serialisation/V1/TimelineSerialiser.cs
index 142bccf3..88674d8e 100644
--- a/VRCOSC.Game/ChatBox/Serialisation/V1/TimelineSerialiser.cs
+++ b/VRCOSC.Game/ChatBox/Serialisation/V1/TimelineSerialiser.cs
@@ -2,9 +2,11 @@
// See the LICENSE file in the repository root for full license text.
using System;
+using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using osu.Framework.Platform;
+using VRCOSC.Game.ChatBox.Clips;
using VRCOSC.Game.ChatBox.Serialisation.V1.Structures;
using VRCOSC.Game.Graphics.Notifications;
using VRCOSC.Game.Managers;
@@ -25,8 +27,6 @@ public TimelineSerialiser(Storage storage, NotificationContainer notification, C
protected override void ExecuteAfterDeserialisation(ChatBoxManager chatBoxManager, SerialisableTimeline data)
{
- chatBoxManager.Clips.Clear();
-
data.Clips.ForEach(clip =>
{
clip.AssociatedModules.ToImmutableList().ForEach(moduleName =>
@@ -54,6 +54,8 @@ protected override void ExecuteAfterDeserialisation(ChatBoxManager chatBoxManage
});
});
+ var createdClips = new List();
+
data.Clips.ForEach(clip =>
{
var newClip = chatBoxManager.CreateClip();
@@ -85,9 +87,10 @@ protected override void ExecuteAfterDeserialisation(ChatBoxManager chatBoxManage
eventData.Length.Value = clipEvent.Length;
});
- chatBoxManager.Clips.Add(newClip);
+ createdClips.Add(newClip);
});
+ chatBoxManager.Clips.ReplaceItems(createdClips);
chatBoxManager.SetTimelineLength(TimeSpan.FromTicks(data.Ticks));
}
}
diff --git a/VRCOSC.Game/Extensions.cs b/VRCOSC.Game/Extensions.cs
index 22a367a0..5777c566 100644
--- a/VRCOSC.Game/Extensions.cs
+++ b/VRCOSC.Game/Extensions.cs
@@ -2,6 +2,9 @@
// See the LICENSE file in the repository root for full license text.
using System;
+using System.Collections.Generic;
+using System.Linq;
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
namespace VRCOSC.Game;
@@ -66,3 +69,17 @@ public static class Colour4Extensions
colour.A
);
}
+
+public static class BindableListExtensions
+{
+ public static void ReplaceItems(this BindableList source, IEnumerable items) => source.ReplaceRange(0, source.Count, items);
+}
+
+public static class AssemblyExtensions
+{
+ public static T? GetAssemblyAttribute(this System.Reflection.Assembly ass) where T : Attribute
+ {
+ var attributes = ass.GetCustomAttributes(typeof(T), false);
+ return attributes.Length == 0 ? null : attributes.OfType().SingleOrDefault();
+ }
+}
diff --git a/VRCOSC.Game/Github/GitHubProvider.cs b/VRCOSC.Game/Github/GitHubProvider.cs
new file mode 100644
index 00000000..a90087d9
--- /dev/null
+++ b/VRCOSC.Game/Github/GitHubProvider.cs
@@ -0,0 +1,26 @@
+// Copyright (c) VolcanicArts. Licensed under the GPL-3.0 License.
+// See the LICENSE file in the repository root for full license text.
+
+using System;
+using System.Threading.Tasks;
+using Octokit;
+
+namespace VRCOSC.Game.Github;
+
+public class GitHubProvider
+{
+ private readonly GitHubClient client;
+
+ public GitHubProvider(string appName)
+ {
+ client = new GitHubClient(new ProductHeaderValue(appName));
+ }
+
+ public Task GetLatestReleaseFor(Uri repoUrl)
+ {
+ var userName = repoUrl.Segments[^2].TrimEnd(new[] { '/' });
+ var repoName = repoUrl.Segments[^1].TrimEnd(new[] { '/' });
+
+ return client.Repository.Release.GetLatest(userName, repoName);
+ }
+}
diff --git a/VRCOSC.Game/Graphics/About/AboutHeader.cs b/VRCOSC.Game/Graphics/About/AboutHeader.cs
index 1bd2b600..d6b3b8e3 100644
--- a/VRCOSC.Game/Graphics/About/AboutHeader.cs
+++ b/VRCOSC.Game/Graphics/About/AboutHeader.cs
@@ -3,6 +3,7 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Framework.Platform;
using VRCOSC.Game.Config;
using VRCOSC.Game.Graphics.Screen;
@@ -10,12 +11,15 @@ namespace VRCOSC.Game.Graphics.About;
public partial class AboutHeader : BaseHeader
{
+ [Resolved]
+ private GameHost host { get; set; } = null!;
+
[Resolved]
private VRCOSCConfigManager configManager { get; set; } = null!;
private Bindable versionBindable = null!;
- protected override string Title => $"VRCOSC {versionBindable.Value}";
+ protected override string Title => $"{host.Name} {versionBindable.Value}";
protected override string SubTitle => "Copyright VolcanicArts 2023. See license file in repository root for more information";
diff --git a/VRCOSC.Game/Graphics/About/AboutScreen.cs b/VRCOSC.Game/Graphics/About/AboutScreen.cs
index 36ced99d..9e97507d 100644
--- a/VRCOSC.Game/Graphics/About/AboutScreen.cs
+++ b/VRCOSC.Game/Graphics/About/AboutScreen.cs
@@ -9,6 +9,7 @@
using osu.Framework.Platform;
using osuTK;
using VRCOSC.Game.Graphics.Screen;
+using VRCOSC.Game.Graphics.Themes;
using VRCOSC.Game.Graphics.UI.Button;
namespace VRCOSC.Game.Graphics.About;
@@ -34,7 +35,7 @@ public sealed partial class AboutScreen : BaseScreen
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.5f, 0.9f),
- Direction = FillDirection.Full,
+ Direction = FillDirection.Vertical,
Spacing = new Vector2(5)
}
}
@@ -45,19 +46,40 @@ private void load()
{
RelativeSizeAxes = Axes.Both;
- buttonFlow.AddRange(new[]
+ buttonFlow.AddRange(new Drawable[]
{
- new AboutButton
+ new FillFlowContainer
{
- Icon = FontAwesome.Brands.Github,
- BackgroundColour = Colour4.FromHex("272b33"),
- Action = () => host.OpenUrlExternally("https://github.com/VolcanicArts/VRCOSC")
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(5, 0),
+ Children = new Drawable[]
+ {
+ new AboutButton
+ {
+ Icon = FontAwesome.Brands.Github,
+ BackgroundColour = Colour4.FromHex("272b33"),
+ Action = () => host.OpenUrlExternally("https://github.com/VolcanicArts/VRCOSC")
+ },
+ new AboutButton
+ {
+ Icon = FontAwesome.Brands.Discord,
+ BackgroundColour = Colour4.FromHex("7289DA"),
+ Action = () => host.OpenUrlExternally("https://discord.gg/vj4brHyvT5")
+ }
+ }
},
- new AboutButton
+ new TextButton
{
- Icon = FontAwesome.Brands.Discord,
- BackgroundColour = Colour4.FromHex("7289DA"),
- Action = () => host.OpenUrlExternally("https://discord.gg/vj4brHyvT5")
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ Size = new Vector2(150, 50),
+ BackgroundColour = ThemeManager.Current[ThemeAttribute.Action],
+ CornerRadius = 5,
+ Text = "Donate",
+ Action = () => host.OpenUrlExternally("https://ko-fi.com/volcanicarts")
}
});
}
@@ -81,7 +103,6 @@ private void load()
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.9f),
- Masking = true,
CornerRadius = 10,
Icon = Icon,
BackgroundColour = BackgroundColour,
diff --git a/VRCOSC.Game/Graphics/ChatBox/ChatBoxScreen.cs b/VRCOSC.Game/Graphics/ChatBox/ChatBoxScreen.cs
index 6f4d150b..507b13b8 100644
--- a/VRCOSC.Game/Graphics/ChatBox/ChatBoxScreen.cs
+++ b/VRCOSC.Game/Graphics/ChatBox/ChatBoxScreen.cs
@@ -5,11 +5,16 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
+using osuTK;
using VRCOSC.Game.Graphics.ChatBox.SelectedClip;
using VRCOSC.Game.Graphics.ChatBox.Timeline;
using VRCOSC.Game.Graphics.ChatBox.Timeline.Menu.Clip;
using VRCOSC.Game.Graphics.ChatBox.Timeline.Menu.Layer;
using VRCOSC.Game.Graphics.Themes;
+using VRCOSC.Game.Graphics.UI.Button;
+using osu.Framework.Platform;
+using VRCOSC.Game.Managers;
+using VRCOSC.Game.Processes;
namespace VRCOSC.Game.Graphics.ChatBox;
@@ -63,12 +68,33 @@ private void load()
null,
new Drawable[]
{
- new TimelineLengthContainer
+ new Container
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Y,
- Width = 300,
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ new FillFlowContainer
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ RelativeSizeAxes = Axes.Y,
+ AutoSizeAxes = Axes.X,
+ Spacing = new Vector2(5, 0),
+ Direction = FillDirection.Horizontal,
+ Children = new Drawable[]
+ {
+ new ImportButton(),
+ new ExportButton()
+ }
+ },
+ new TimelineLengthContainer
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Y,
+ Width = 300,
+ }
+ }
}
},
null,
@@ -88,4 +114,53 @@ private void load()
clipMenu
};
}
+
+ private partial class ImportButton : TextButton
+ {
+ [Resolved]
+ private ChatBoxManager chatBoxManager { get; set; } = null!;
+
+ public ImportButton()
+ {
+ Anchor = Anchor.CentreLeft;
+ Origin = Anchor.CentreLeft;
+ Size = new Vector2(110, 30);
+ Text = "Import Config";
+ FontSize = 18;
+ CornerRadius = 5;
+ BackgroundColour = ThemeManager.Current[ThemeAttribute.Action];
+ BorderThickness = 2;
+ }
+
+ protected override void LoadComplete()
+ {
+ Action += () => WinForms.OpenFileDialog(@"chatbox.json|*.json", fileName => Schedule(() => chatBoxManager.Import(fileName)));
+ }
+ }
+
+ private partial class ExportButton : TextButton
+ {
+ [Resolved]
+ private GameHost host { get; set; } = null!;
+
+ [Resolved]
+ private Storage storage { get; set; } = null!;
+
+ public ExportButton()
+ {
+ Anchor = Anchor.CentreLeft;
+ Origin = Anchor.CentreLeft;
+ Size = new Vector2(110, 30);
+ Text = "Export Config";
+ FontSize = 18;
+ CornerRadius = 5;
+ BackgroundColour = ThemeManager.Current[ThemeAttribute.Action];
+ BorderThickness = 2;
+ }
+
+ protected override void LoadComplete()
+ {
+ Action += () => host.PresentFileExternally(storage.GetFullPath(@"chatbox.json"));
+ }
+ }
}
diff --git a/VRCOSC.Game/Graphics/ChatBox/Metadata/MetadataToggle.cs b/VRCOSC.Game/Graphics/ChatBox/Metadata/MetadataToggle.cs
index e9826ef8..87e66484 100644
--- a/VRCOSC.Game/Graphics/ChatBox/Metadata/MetadataToggle.cs
+++ b/VRCOSC.Game/Graphics/ChatBox/Metadata/MetadataToggle.cs
@@ -70,10 +70,7 @@ private void load()
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
State = State,
- Masking = true,
- CornerRadius = 5,
BorderThickness = 2,
- BorderColour = ThemeManager.Current[ThemeAttribute.Border],
ShouldAnimate = false
}
}
diff --git a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableAssociatedModule.cs b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableAssociatedModule.cs
index 14603b67..f0e05c71 100644
--- a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableAssociatedModule.cs
+++ b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableAssociatedModule.cs
@@ -74,7 +74,6 @@ private void load()
State = State.GetBoundCopy(),
BorderThickness = 2,
ShouldAnimate = false,
- BorderColour = ThemeManager.Current[ThemeAttribute.Border]
}
}
}
diff --git a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableEvent.cs b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableEvent.cs
index 3213d63a..6f25a096 100644
--- a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableEvent.cs
+++ b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableEvent.cs
@@ -70,7 +70,6 @@ private void load()
RelativeSizeAxes = Axes.Both,
State = ClipEvent.Enabled.GetBoundCopy(),
BorderThickness = 2,
- BorderColour = ThemeManager.Current[ThemeAttribute.Border],
ShouldAnimate = false
}
},
@@ -117,7 +116,8 @@ private void load()
Masking = true,
CornerRadius = 5,
BorderThickness = 2,
- BorderColour = ThemeManager.Current[ThemeAttribute.Border]
+ BorderColour = ThemeManager.Current[ThemeAttribute.Border],
+ UnicodeSupport = true
}
},
null,
diff --git a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableState.cs b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableState.cs
index 5e2b2472..bf0a117c 100644
--- a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableState.cs
+++ b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/DrawableState.cs
@@ -83,7 +83,6 @@ private void load()
RelativeSizeAxes = Axes.Both,
State = ClipState.Enabled.GetBoundCopy(),
BorderThickness = 2,
- BorderColour = ThemeManager.Current[ThemeAttribute.Border],
ShouldAnimate = false
}
},
@@ -114,7 +113,8 @@ private void load()
Masking = true,
CornerRadius = 5,
BorderThickness = 2,
- BorderColour = ThemeManager.Current[ThemeAttribute.Border]
+ BorderColour = ThemeManager.Current[ThemeAttribute.Border],
+ UnicodeSupport = true
}
}
}
diff --git a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipEditorWrapper.cs b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipEditorWrapper.cs
index d3f40ead..390c252f 100644
--- a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipEditorWrapper.cs
+++ b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipEditorWrapper.cs
@@ -86,13 +86,13 @@ private void load()
RelativeSizeAxes = Axes.Both,
ColumnDimensions = new[]
{
- new Dimension(GridSizeMode.Relative, 0.15f),
+ new Dimension(GridSizeMode.Relative, 0.15f, 0, 200),
new Dimension(GridSizeMode.Absolute, 5),
- new Dimension(GridSizeMode.Relative, 0.15f),
+ new Dimension(GridSizeMode.Relative, 0.15f, 0, 200),
new Dimension(GridSizeMode.Absolute, 5),
new Dimension(),
new Dimension(GridSizeMode.Absolute, 5),
- new Dimension(GridSizeMode.Relative, 0.2f),
+ new Dimension(GridSizeMode.Relative, 0.2f, 0, 300),
},
Content = new[]
{
diff --git a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipModuleSelector.cs b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipModuleSelector.cs
index 9591f50e..acf2ae66 100644
--- a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipModuleSelector.cs
+++ b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipModuleSelector.cs
@@ -99,7 +99,7 @@ private void load()
moduleFlow.Clear();
- foreach (var module in gameManager.ModuleManager.Where(module => module.GetType().IsSubclassOf(typeof(ChatBoxModule))))
+ foreach (var module in gameManager.ModuleManager.Modules.Where(module => module.GetType().IsSubclassOf(typeof(ChatBoxModule))))
{
DrawableAssociatedModule drawableAssociatedModule;
diff --git a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipStateEditorContainer.cs b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipStateEditorContainer.cs
index 287403da..bd4d3865 100644
--- a/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipStateEditorContainer.cs
+++ b/VRCOSC.Game/Graphics/ChatBox/SelectedClip/SelectedClipStateEditorContainer.cs
@@ -197,6 +197,7 @@ private void load()
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
+ Font = FrameworkFont.Regular.With(size: 20),
Text = "Show relevant states only (Based on enabled modules)",
Colour = ThemeManager.Current[ThemeAttribute.SubText]
}
diff --git a/VRCOSC.Game/Graphics/ChatBox/Timeline/DrawableClip.cs b/VRCOSC.Game/Graphics/ChatBox/Timeline/DrawableClip.cs
index 7fd14a7b..99415797 100644
--- a/VRCOSC.Game/Graphics/ChatBox/Timeline/DrawableClip.cs
+++ b/VRCOSC.Game/Graphics/ChatBox/Timeline/DrawableClip.cs
@@ -57,28 +57,36 @@ private void load()
Colour = ThemeManager.Current[ThemeAttribute.Dark],
RelativeSizeAxes = Axes.Both
},
- new StartResizeDetector(Clip)
- {
- RelativeSizeAxes = Axes.Y,
- Width = 15
- },
- new EndResizeDetector(Clip)
- {
- RelativeSizeAxes = Axes.Y,
- Width = 15
- },
new Container
{
RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding(10),
+ Padding = new MarginPadding(2),
Children = new Drawable[]
{
- drawName = new SpriteText
+ new StartResizeDetector(Clip)
+ {
+ RelativeSizeAxes = Axes.Y,
+ Width = 12
+ },
+ new EndResizeDetector(Clip)
+ {
+ RelativeSizeAxes = Axes.Y,
+ Width = 12
+ },
+ new Container
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = FrameworkFont.Regular.With(size: 20),
- Colour = ThemeManager.Current[ThemeAttribute.Text]
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding(10),
+ Children = new Drawable[]
+ {
+ drawName = new SpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = FrameworkFont.Regular.With(size: 20),
+ Colour = ThemeManager.Current[ThemeAttribute.Text]
+ }
+ }
}
}
}
diff --git a/VRCOSC.Game/Graphics/ModuleAttributes/Attributes/AttributeCard.cs b/VRCOSC.Game/Graphics/ModuleAttributes/Attributes/AttributeCard.cs
index d161a420..19a8933f 100644
--- a/VRCOSC.Game/Graphics/ModuleAttributes/Attributes/AttributeCard.cs
+++ b/VRCOSC.Game/Graphics/ModuleAttributes/Attributes/AttributeCard.cs
@@ -1,7 +1,6 @@
// Copyright (c) VolcanicArts. Licensed under the GPL-3.0 License.
// See the LICENSE file in the repository root for full license text.
-using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@@ -9,22 +8,21 @@
using osuTK;
using VRCOSC.Game.Graphics.Themes;
using VRCOSC.Game.Graphics.UI.Button;
-using VRCOSC.Game.Modules;
+using VRCOSC.Game.Modules.Attributes;
namespace VRCOSC.Game.Graphics.ModuleAttributes.Attributes;
-public abstract partial class AttributeCard : Container
+public abstract partial class AttributeCard : Container where T : ModuleAttribute
{
private readonly VRCOSCButton resetToDefault;
protected override FillFlowContainer Content { get; }
- public readonly ModuleAttribute AttributeData;
- public bool Enable { get; set; } = true;
+ protected readonly T AttributeData;
- protected override bool ShouldBeConsideredForInput(Drawable child) => Enable;
+ protected override bool ShouldBeConsideredForInput(Drawable child) => AttributeData.Enabled;
- protected AttributeCard(ModuleAttribute attributeData)
+ protected AttributeCard(T attributeData)
{
AttributeData = attributeData;
@@ -49,9 +47,8 @@ protected AttributeCard(ModuleAttribute attributeData)
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
- Action = SetDefault,
+ Action = setDefault,
BorderThickness = 2,
- BorderColour = ThemeManager.Current[ThemeAttribute.Border],
BackgroundColour = ThemeManager.Current[ThemeAttribute.Action],
Icon = FontAwesome.Solid.Undo,
IconPadding = 7,
@@ -116,50 +113,30 @@ protected AttributeCard(ModuleAttribute attributeData)
}
};
- textFlow.AddText(AttributeData.Metadata.DisplayName, t =>
+ textFlow.AddText(AttributeData.Name, t =>
{
t.Font = FrameworkFont.Regular.With(size: 25);
t.Colour = ThemeManager.Current[ThemeAttribute.Text];
});
- textFlow.AddParagraph(AttributeData.Metadata.Description, t =>
+ textFlow.AddParagraph(AttributeData.Description, t =>
{
t.Font = FrameworkFont.Regular.With(size: 20);
t.Colour = ThemeManager.Current[ThemeAttribute.SubText];
});
}
- protected override void LoadComplete()
+ protected override void Update()
{
- AttributeData.Attribute.BindValueChanged(onAttributeUpdate, true);
+ resetToDefault.FadeTo(AttributeData.IsDefault() ? 0 : 1, 200, Easing.OutQuart);
+ this.FadeTo(AttributeData.Enabled ? 1 : 0.5f, 150, Easing.OutQuart);
}
- protected virtual void SetDefault()
+ private void setDefault()
{
- AttributeData.Attribute.SetDefault();
+ AttributeData.SetDefault();
+ OnSetDefault();
}
- protected void UpdateResetToDefault(bool show)
- {
- resetToDefault.FadeTo(show ? 1 : 0, 200, Easing.OutQuart);
- }
-
- protected void UpdateAttribute(object value)
- {
- //Specifically check for equal values here to stop memory allocations from setting the value
- if (value == AttributeData.Attribute.Value) return;
-
- AttributeData.Attribute.Value = value;
- }
-
- private void onAttributeUpdate(ValueChangedEvent