Skip to content

Commit 9c67d86

Browse files
committed
Make event button position relative to background
Previously, the position and the size of the event button is static. The size and the position of the button should now be relative to the size of the background canvas. Also, the button should now only display on official backgrounds.
1 parent ee13b0b commit 9c67d86

14 files changed

Lines changed: 217 additions & 85 deletions

File tree

CollapseLauncher/Classes/GameManagement/ImageBackground/ImageBackgroundManager.Loaders.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using System.Runtime.CompilerServices;
2020
using System.Threading;
2121
using System.Threading.Tasks;
22+
using Windows.Foundation;
2223
using Windows.UI;
2324
// ReSharper disable IdentifierTypo
2425

@@ -240,12 +241,19 @@ private void SpawnImageLayer(Uri? overlayFilePath,
240241
bindingMode: BindingMode.OneWay,
241242
converter: StaticConverter<InverseBooleanConverter>.Shared);
242243

243-
layerElement.ImageLoaded += LayerElementOnLoaded;
244+
layerElement.ImageLoaded += LayerElementOnLoaded;
245+
layerElement.CanvasSizeChanged += LayerElementCanvasSizeChanged;
244246
PresenterGrid?.Children.Add(layerElement);
245247

246248
layerElement.Tag = isVideo;
247249
}
248250

251+
private void LayerElementCanvasSizeChanged(LayeredBackgroundImage layerElement, Size size)
252+
{
253+
CurrentElementWidth = size.Width;
254+
CurrentElementHeight = size.Height;
255+
}
256+
249257
private void LayerElementOnLoaded(LayeredBackgroundImage layerElement)
250258
{
251259
layerElement.Transitions.Add(new PopupThemeTransition());
@@ -257,6 +265,10 @@ private void LayerElementOnLoaded(LayeredBackgroundImage layerElement)
257265
foreach (UIElement element in PresenterGrid?.Children.Where(element => element != lastElement) ?? [])
258266
{
259267
PresenterGrid?.Children.Remove(element);
268+
if (element is LayeredBackgroundImage asLayeredImage)
269+
{
270+
asLayeredImage.CanvasSizeChanged -= LayerElementCanvasSizeChanged;
271+
}
260272
}
261273
}
262274

CollapseLauncher/Classes/GameManagement/ImageBackground/ImageBackgroundManager.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,26 @@ private set
300300
}
301301
}
302302

303+
public double CurrentElementWidth
304+
{
305+
get;
306+
set
307+
{
308+
field = value;
309+
OnPropertyChanged();
310+
}
311+
}
312+
313+
public double CurrentElementHeight
314+
{
315+
get;
316+
set
317+
{
318+
field = value;
319+
OnPropertyChanged();
320+
}
321+
}
322+
303323
/// <summary>
304324
/// The collection of image context sources.<br/><br/>
305325
/// Notes to Dev:<br/>
@@ -395,7 +415,8 @@ await SetGlobalCustomBackground(GlobalCustomBackgroundImagePath, false, false, t
395415
{
396416
OriginBackgroundImagePath = bgPlaceholderPath,
397417
BackgroundImagePath = bgPlaceholderPath,
398-
IsVideo = IsVideoMediaFileExtensionSupported(bgPlaceholderPath)
418+
IsVideo = IsVideoMediaFileExtensionSupported(bgPlaceholderPath),
419+
IsCustom = true
399420
});
400421
return;
401422
}
@@ -643,6 +664,12 @@ public bool IsVideo
643664
init;
644665
}
645666

667+
public bool IsCustom
668+
{
669+
get;
670+
init;
671+
}
672+
646673
public bool Equals(LayeredImageBackgroundContext? other) => other?.GetHashCode() == GetHashCode();
647674

648675
public override bool Equals(object? obj)

CollapseLauncher/Classes/Helper/Animation/AnimationHelper.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ internal static void EnableImplicitAnimation(this UIElement element, bool recurs
163163

164164
switch (element)
165165
{
166+
case Viewbox { Child: { } viewBoxContent }:
167+
viewBoxContent.EnableImplicitAnimation(true, easingFunction);
168+
break;
166169
case Button { Content: UIElement buttonContent }:
167170
buttonContent.EnableImplicitAnimation(true, easingFunction);
168171
break;

CollapseLauncher/Classes/Helper/Metadata/PresetConfig.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Hi3Helper.EncTool;
88
using Hi3Helper.EncTool.Parser.AssetMetadata;
99
using Hi3Helper.SentryHelper;
10+
using Microsoft.UI.Xaml;
1011
using Microsoft.Win32;
1112
using System;
1213
using System.Buffers;
@@ -20,6 +21,7 @@
2021
using System.Text.Json.Serialization;
2122
using System.Threading;
2223
using System.Threading.Tasks;
24+
using WinRT;
2325
using static Hi3Helper.Logger;
2426
// ReSharper disable InconsistentNaming
2527
// ReSharper disable IdentifierTypo
@@ -80,6 +82,19 @@ public enum LauncherType
8082
Plugin
8183
}
8284

85+
[GeneratedBindableCustomProperty]
86+
public partial class GameEventButtonPosition
87+
{
88+
[JsonConverter(typeof(JsonStringEnumConverter<HorizontalAlignment>))]
89+
public HorizontalAlignment HorizontalAlignment { get; init; } = HorizontalAlignment.Left;
90+
91+
[JsonConverter(typeof(JsonStringEnumConverter<VerticalAlignment>))]
92+
public VerticalAlignment VerticalAlignment { get; init; } = VerticalAlignment.Top;
93+
94+
public Thickness Position { get; init; } = new(256, 596, 0, 0);
95+
public double VSize { get; init; } = 80d;
96+
}
97+
8398
public class GameInstallFileInfo
8499
{
85100
public string GameDataFolderName { get; init; } = string.Empty;
@@ -539,6 +554,8 @@ public SophonChunkUrls? LauncherResourceChunksURL
539554

540555
public GameInstallFileInfo? GameInstallFileInfo { get; init; }
541556

557+
public GameEventButtonPosition GameEventButtonPosition { get => field ??= new GameEventButtonPosition(); init; }
558+
542559
#endregion
543560

544561
#region Dynamic Config Properties

CollapseLauncher/Classes/RegionManagement/RegionManagement.cs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
using System.Threading.Tasks;
2121
using static CollapseLauncher.InnerLauncherConfig;
2222
using static Hi3Helper.Logger;
23-
using static Hi3Helper.Shared.Region.LauncherConfig;
2423
// ReSharper disable StringLiteralTypo
2524
// ReSharper disable CheckNamespace
2625

26+
#nullable enable
2727
namespace CollapseLauncher
2828
{
2929
[SuppressMessage("ReSharper", "InconsistentNaming")]
@@ -32,8 +32,10 @@ namespace CollapseLauncher
3232
[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
3333
public sealed partial class MainPage
3434
{
35-
private GamePresetProperty CurrentGameProperty { get; set; }
36-
private bool IsLoadRegionComplete;
35+
public GamePresetProperty? CurrentGameProperty { get; set; }
36+
private bool IsLoadRegionComplete;
37+
38+
public PresetConfig? CurrentPresetConfig => CurrentGameProperty?.GamePreset;
3739

3840
private static string RegionToChangeName => MetadataHelper.GetCurrentTranslatedTitleRegion();
3941

@@ -53,13 +55,13 @@ private async Task<bool> LoadRegionFromCurrentConfigV2(PresetConfig preset, stri
5355

5456
CancellationTokenSourceWrapper tokenSource = new();
5557

56-
string regionToChangeName = $"{preset.GameLauncherApi.GameNameTranslation} - {preset.GameLauncherApi.GameRegionTranslation}";
57-
bool runResult = await preset.GameLauncherApi
58+
string regionToChangeName = $"{preset.GameLauncherApi?.GameNameTranslation} - {preset.GameLauncherApi?.GameRegionTranslation}";
59+
bool runResult = await (preset.GameLauncherApi?
5860
.LoadAsync(BeforeLoadRoutine,
5961
AfterLoadRoutine,
6062
ActionOnTimeOutRetry,
6163
OnErrorRoutine,
62-
tokenSource.Token);
64+
tokenSource.Token) ?? ValueTask.FromResult(false));
6365

6466
RegionLoadingStatus.Remove((gameName, gameRegion));
6567
return runResult;
@@ -127,6 +129,12 @@ async ValueTask AfterLoadRoutine(CancellationToken token)
127129
preset.GameLauncherApi.LauncherGameBackground,
128130
presenterGrid: BackgroundPresenterGrid,
129131
token: token);
132+
133+
DispatcherQueueExtensions.TryEnqueue(() =>
134+
{
135+
OnPropertyChanged(nameof(CurrentPresetConfig));
136+
OnPropertyChanged(nameof(CurrentGameBackgroundData));
137+
});
130138
}
131139
catch (Exception ex)
132140
{
@@ -182,7 +190,7 @@ private void ClearMainPageState()
182190

183191
private async Task FinalizeLoadRegion(string gameName, string gameRegion, CancellationToken token)
184192
{
185-
if (!MetadataHelper.TryGetGameConfig(gameName, gameRegion, out PresetConfig preset))
193+
if (!MetadataHelper.TryGetGameConfig(gameName, gameRegion, out PresetConfig? preset))
186194
{
187195
return;
188196
}
@@ -205,12 +213,12 @@ private async Task LoadGameStaticsByGameType(PresetConfig preset, string gameNam
205213

206214
// Load region property (and potentially, cached one)
207215
GamePropertyVault.RegisterGameProperty(this,
208-
preset.GameLauncherApi,
216+
preset.GameLauncherApi!,
209217
gameName,
210218
gameRegion);
211219

212220
// Spawn Region Notification
213-
_ = SpawnRegionNotification(preset.ProfileName);
221+
_ = SpawnRegionNotification(preset.ProfileName ?? "");
214222
}
215223

216224
private void DisposeAllPageStatics()
@@ -234,7 +242,7 @@ private async Task SpawnRegionNotification(string RegionProfileName)
234242
await Task.Delay(250);
235243
}
236244

237-
if (NotificationData.RegionPush == null) return;
245+
if (NotificationData?.RegionPush == null) return;
238246
List<NotificationProp> regionPushCopy = new(NotificationData.RegionPush);
239247

240248
foreach (NotificationProp Entry in regionPushCopy)
@@ -293,7 +301,7 @@ private async void ChangeRegionNoWarning(object sender, RoutedEventArgs e)
293301
{
294302
try
295303
{
296-
(sender as Button).IsEnabled = false;
304+
(sender as Button)?.IsEnabled = false;
297305
if (!IsLoadRegionComplete)
298306
{
299307
return;
@@ -396,7 +404,7 @@ private async Task<bool> LoadRegionRootButton()
396404

397405
// Start region loading
398406
_ = ShowAsyncLoadingTimedOutPill();
399-
if (!await LoadRegionFromCurrentConfigV2(gameRegion, gameTitle, gameRegion.ZoneName))
407+
if (!await LoadRegionFromCurrentConfigV2(gameRegion, gameTitle, gameRegion.ZoneName ?? ""))
400408
{
401409
return false;
402410
}
@@ -428,7 +436,7 @@ private void ToggleChangeRegionBtn(in object sender, bool IsHide)
428436
LauncherFrame.BackStack.Clear();
429437
}
430438

431-
(sender as Button).IsEnabled = !IsHide;
439+
(sender as Button)?.IsEnabled = !IsHide;
432440
}
433441

434442
private async Task ShowAsyncLoadingTimedOutPill(CancellationToken token = default)
@@ -445,7 +453,7 @@ private async Task ShowAsyncLoadingTimedOutPill(CancellationToken token = defaul
445453
if (!IsLoadRegionComplete &&
446454
!token.IsCancellationRequested)
447455
{
448-
InvokeLoadingRegionPopup(true, Locale.Current.Lang?._MainPage?.RegionLoadingTitle, RegionToChangeName);
456+
InvokeLoadingRegionPopup(true, Locale.Current.Lang?._MainPage?.RegionLoadingTitle ?? "", RegionToChangeName);
449457
}
450458
}
451459
catch (Exception ex)
@@ -455,7 +463,7 @@ private async Task ShowAsyncLoadingTimedOutPill(CancellationToken token = defaul
455463
}
456464
}
457465

458-
private static void InvokeLoadingRegionPopup(bool ShowLoadingMessage = true, string Title = null, string Message = null)
466+
private static void InvokeLoadingRegionPopup(bool ShowLoadingMessage = true, string? Title = null, string? Message = null)
459467
{
460468
if (ShowLoadingMessage)
461469
{

CollapseLauncher/XAMLs/MainApp/MainPage.xaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@
1515
<Thickness x:Key="NavigationViewContentGridBorderThickness">0</Thickness>
1616
<ListView x:Name="KeyboardHandler" />
1717
<pages:BooleanToOpacityConverter x:Key="BooleanToOpacityConverter" />
18+
<pages:BooleanVisibilityConverter x:Key="BooleanVisibilityConverter" />
1819
<pages:InverseBooleanToOpacityConverter x:Key="InverseBooleanToOpacityConverter" />
20+
<pages:InverseBooleanVisibilityConverter x:Key="InverseBooleanVisibilityConverter" />
1921
<pages:CountToVisibilityConverter x:Key="CountToVisibilityConverter" />
2022
<pages:CountToOpacityConverter x:Key="CountToOpacityConverter" />
23+
<pages:NullableVisibilityConverter x:Key="NullableVisibilityConverter" />
2124
<pages:InverseCountToOpacityConverter x:Key="InverseCountToOpacityConverter" />
2225
<pages:GameTitleComboBoxTranslatedConverter x:Key="GameTitleComboBoxTranslatedConverter" />
2326
<pages:GameRegionComboBoxTranslatedConverter x:Key="GameRegionComboBoxTranslatedConverter" />
2427
<pages:StringUppercaseConverter x:Key="StringUppercaseConverter" />
2528
<pages:GameChannelToVisibilityConverter x:Key="GameChannelToVisibilityConverter" />
29+
<pages:UrlToCachedImagePathConverter x:Key="UrlToCachedImagePathConverter" />
2630
</Page.Resources>
2731
<Grid x:Name="MainPageGrid"
2832
Background="{ThemeResource WindowBackground}">
@@ -108,6 +112,37 @@
108112
</Frame>
109113
</Grid>
110114
</NavigationView>
115+
<Viewbox x:Name="ImageEventImgViewBox"
116+
Grid.Row="0"
117+
Grid.Column="0"
118+
DataContext="{x:Bind CurrentGameBackgroundData, Mode=OneWay}"
119+
Stretch="UniformToFill"
120+
HorizontalAlignment="Center"
121+
VerticalAlignment="Center"
122+
Visibility="{Binding FeaturedEventIconUrl, Mode=OneWay, Converter={StaticResource NullableVisibilityConverter}}">
123+
<Grid DataContext="{x:Bind CurrentBackgroundManager, Mode=OneWay}"
124+
Visibility="{Binding CurrentSelectedBackgroundContext.IsCustom, Mode=OneWay, Converter={StaticResource InverseBooleanVisibilityConverter}}">
125+
<Grid Width="{Binding CurrentElementWidth, Mode=OneWay}"
126+
Height="{Binding CurrentElementHeight, Mode=OneWay}"
127+
HorizontalAlignment="Center"
128+
VerticalAlignment="Center"
129+
Visibility="{Binding IsBackgroundElevated, Mode=OneWay, Converter={StaticResource InverseBooleanVisibilityConverter}}">
130+
<customControls:NonFaultyImageEx
131+
x:Name="ImageEventImg"
132+
x:FieldModifier="internal"
133+
extension:UIElementExtensions.CursorType="Hand"
134+
PointerPressed="ClickImageEventSpriteLink"
135+
DataContext="{x:Bind CurrentGameBackgroundData, Mode=OneWay}"
136+
HorizontalAlignment="{x:Bind CurrentPresetConfig.GameEventButtonPosition.HorizontalAlignment, Mode=OneWay}"
137+
VerticalAlignment="{x:Bind CurrentPresetConfig.GameEventButtonPosition.VerticalAlignment, Mode=OneWay}"
138+
Height="{x:Bind CurrentPresetConfig.GameEventButtonPosition.VSize, Mode=OneWay}"
139+
Margin="{x:Bind CurrentPresetConfig.GameEventButtonPosition.Position, Mode=OneWay}"
140+
Visibility="{x:Bind NeedShowEventIcon, Mode=OneWay, Converter={StaticResource BooleanVisibilityConverter}}"
141+
Source="{Binding FeaturedEventIconUrl, Mode=OneWay, Converter={StaticResource UrlToCachedImagePathConverter}}"
142+
Tag="{Binding FeaturedEventIconClickLink, Mode=OneWay}"/>
143+
</Grid>
144+
</Grid>
145+
</Viewbox>
111146
<Grid Height="47"
112147
HorizontalAlignment="Stretch"
113148
VerticalAlignment="Top">

0 commit comments

Comments
 (0)