From faa6a6ca8e8c5a2b5dd3f0cebb05f308fe1bdff1 Mon Sep 17 00:00:00 2001 From: Alexa <67791946+GoingCrazyDude@users.noreply.github.com> Date: Sun, 5 Apr 2026 21:23:51 +0530 Subject: [PATCH 1/3] Add MediaElement support --- .../Resources/CustomBootstrapperSchema.json | 13 ++++++++- .../Bootstrapper/CustomDialog.Creator.cs | 1 + .../Bootstrapper/CustomDialog.Elements.cs | 29 +++++++++++++++++++ .../Bootstrapper/CustomDialog.Utilities.cs | 20 +++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/Bloxstrap/Resources/CustomBootstrapperSchema.json b/Bloxstrap/Resources/CustomBootstrapperSchema.json index b8d068086..b3cf5366c 100644 --- a/Bloxstrap/Resources/CustomBootstrapperSchema.json +++ b/Bloxstrap/Resources/CustomBootstrapperSchema.json @@ -124,7 +124,17 @@ "StretchDirection": "StretchDirection", "Source": "ImageSource", "IsAnimated": "bool", - "RepeatBehavior": "RepeatBehavior" + "RepeatBehavior": "RepeatBehavior" + } + }, + "MediaElement": { + "SuperClass": "FrameworkElement", + "IsCreatable": true, + "Attributes": { + "Stretch": "Stretch", + "StretchDirection": "StretchDirection", + "Source": "Uri", + "Volume": "double" } }, "Grid": { @@ -322,6 +332,7 @@ "Rect": {}, "Point": {}, "CornerRadius": {}, + "Uri": {}, "Brush": { "CanHaveElement": true }, "Color": {}, "ImageSource": {}, diff --git a/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Creator.cs b/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Creator.cs index e5f0c29b5..b3e3c57db 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Creator.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Creator.cs @@ -30,6 +30,7 @@ private class DummyFrameworkElement : FrameworkElement { } ["TextBlock"] = HandleXmlElement_TextBlock, ["MarkdownTextBlock"] = HandleXmlElement_MarkdownTextBlock, ["Image"] = HandleXmlElement_Image, + ["MediaElement"] = HandleXmlElement_MediaElement, ["Grid"] = HandleXmlElement_Grid, ["StackPanel"] = HandleXmlElement_StackPanel, ["Border"] = HandleXmlElement_Border, diff --git a/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Elements.cs b/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Elements.cs index 7576aa295..7c010ff95 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Elements.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Elements.cs @@ -638,6 +638,35 @@ private static UIElement HandleXmlElement_Image(CustomDialog dialog, XElement xm return image; } + private static UIElement HandleXmlElement_MediaElement(CustomDialog dialog, XElement xmlElement) + { + var media = new MediaElement(); + HandleXmlElement_FrameworkElement(dialog, media, xmlElement); + + RenderOptions.SetBitmapScalingMode(media, BitmapScalingMode.HighQuality); // i think letting this be modifiable would be funny + + // should behaviour be modifiable? (except unloadedbehavior ig) + media.LoadedBehavior = MediaState.Play; + media.UnloadedBehavior = MediaState.Close; + + media.Volume = ParseXmlAttribute(xmlElement, "Volume", 1); + + media.Stretch = ParseXmlAttribute(xmlElement, "Stretch", Stretch.Uniform); + media.StretchDirection = ParseXmlAttribute(xmlElement, "StretchDirection", StretchDirection.Both); + + media.Source = GetMediaSourceData(dialog, "Source", xmlElement); + + if (ParseXmlAttribute(xmlElement, "Looped", true)) + { + media.MediaEnded += (Sender, e) => + { + media.Position = TimeSpan.Zero; + }; + } + + return media; + } + private static RowDefinition HandleXmlElement_RowDefinition(CustomDialog dialog, XElement xmlElement) { var rowDefinition = new RowDefinition(); diff --git a/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Utilities.cs b/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Utilities.cs index 0deafb3c4..04b9c3276 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Utilities.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Utilities.cs @@ -230,6 +230,26 @@ private static GetImageSourceDataResult GetImageSourceData(CustomDialog dialog, return new GetImageSourceDataResult { Uri = result }; } + private static Uri GetMediaSourceData(CustomDialog dialog, string name, XElement xmlElement) + { + string path = GetXmlAttribute(xmlElement, name); + + path = GetFullPath(dialog, path)!; + + if (!Uri.TryCreate(path, UriKind.RelativeOrAbsolute, out Uri? result)) + throw new CustomThemeException("CustomTheme.Errors.ElementAttributeParseError", xmlElement.Name, name, "Uri"); + + if (result == null) + throw new CustomThemeException("CustomTheme.Errors.ElementAttributeParseErrorNull", xmlElement.Name, name, "Uri"); + + if (result.Scheme != "file") + throw new CustomThemeException("CustomTheme.Errors.ElementAttributeBlacklistedUriScheme", xmlElement.Name, name, result.Scheme); + + Uri uri = result; + + return uri; + } + private static object? GetContentFromXElement(CustomDialog dialog, XElement xmlElement) { var contentAttr = xmlElement.Attribute("Content"); From 5ed672cca62c08edc73f88e9b22ab38ab3033193 Mon Sep 17 00:00:00 2001 From: Alexa <67791946+GoingCrazyDude@users.noreply.github.com> Date: Sun, 5 Apr 2026 21:55:14 +0530 Subject: [PATCH 2/3] Add missing field --- Bloxstrap/Resources/CustomBootstrapperSchema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Bloxstrap/Resources/CustomBootstrapperSchema.json b/Bloxstrap/Resources/CustomBootstrapperSchema.json index b3cf5366c..21ad31c89 100644 --- a/Bloxstrap/Resources/CustomBootstrapperSchema.json +++ b/Bloxstrap/Resources/CustomBootstrapperSchema.json @@ -134,7 +134,8 @@ "Stretch": "Stretch", "StretchDirection": "StretchDirection", "Source": "Uri", - "Volume": "double" + "Volume": "double", + "Looped": "bool" } }, "Grid": { From 8efa4d0cce2e6ff7ec0e95b6425593f86d3689ea Mon Sep 17 00:00:00 2001 From: Alexa <67791946+GoingCrazyDude@users.noreply.github.com> Date: Mon, 6 Apr 2026 10:33:50 +0530 Subject: [PATCH 3/3] Fix with requested changes --- Bloxstrap/Resources/CustomBootstrapperSchema.json | 1 - Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Elements.cs | 6 +++--- .../UI/Elements/Bootstrapper/CustomDialog.Utilities.cs | 4 +--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Bloxstrap/Resources/CustomBootstrapperSchema.json b/Bloxstrap/Resources/CustomBootstrapperSchema.json index 21ad31c89..c2f2dd810 100644 --- a/Bloxstrap/Resources/CustomBootstrapperSchema.json +++ b/Bloxstrap/Resources/CustomBootstrapperSchema.json @@ -134,7 +134,6 @@ "Stretch": "Stretch", "StretchDirection": "StretchDirection", "Source": "Uri", - "Volume": "double", "Looped": "bool" } }, diff --git a/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Elements.cs b/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Elements.cs index 7c010ff95..925f4ecce 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Elements.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Elements.cs @@ -643,20 +643,20 @@ private static UIElement HandleXmlElement_MediaElement(CustomDialog dialog, XEle var media = new MediaElement(); HandleXmlElement_FrameworkElement(dialog, media, xmlElement); - RenderOptions.SetBitmapScalingMode(media, BitmapScalingMode.HighQuality); // i think letting this be modifiable would be funny + RenderOptions.SetBitmapScalingMode(media, BitmapScalingMode.HighQuality); // should behaviour be modifiable? (except unloadedbehavior ig) media.LoadedBehavior = MediaState.Play; media.UnloadedBehavior = MediaState.Close; - media.Volume = ParseXmlAttribute(xmlElement, "Volume", 1); + media.Volume = 0; media.Stretch = ParseXmlAttribute(xmlElement, "Stretch", Stretch.Uniform); media.StretchDirection = ParseXmlAttribute(xmlElement, "StretchDirection", StretchDirection.Both); media.Source = GetMediaSourceData(dialog, "Source", xmlElement); - if (ParseXmlAttribute(xmlElement, "Looped", true)) + if (ParseXmlAttribute(xmlElement, "Looped", false)) { media.MediaEnded += (Sender, e) => { diff --git a/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Utilities.cs b/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Utilities.cs index 04b9c3276..320bf053d 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Utilities.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/CustomDialog.Utilities.cs @@ -245,9 +245,7 @@ private static Uri GetMediaSourceData(CustomDialog dialog, string name, XElement if (result.Scheme != "file") throw new CustomThemeException("CustomTheme.Errors.ElementAttributeBlacklistedUriScheme", xmlElement.Name, name, result.Scheme); - Uri uri = result; - - return uri; + return result; } private static object? GetContentFromXElement(CustomDialog dialog, XElement xmlElement)