Implement navigation with animations

This commit is contained in:
Yoshi Askharoun
2024-05-12 12:34:25 -05:00
parent cd35c50136
commit 83fc693a8a
5 changed files with 205 additions and 14 deletions
+21 -6
View File
@@ -5,6 +5,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:zmh="clr-namespace:ZuneModdingHelper"
xmlns:zmhc="clr-namespace:ZuneModdingHelper.Controls"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:b="clr-namespace:ZuneModdingHelper.Behaviors"
mc:Ignorable="d"
WindowStyle="None"
Title="{x:Static zmh:App.Title}" Height="450" Width="800" WindowStartupLocation="CenterScreen">
@@ -74,18 +76,31 @@
<StackPanel x:Name="Pivot" Grid.Row="1" VerticalAlignment="Bottom" Orientation="Horizontal">
<zmhc:TextButton Text="Mods" Grid.Column="0" Width="36"
Checked="PivotButton_Checked" Style="{StaticResource PivotButtonStyle}" />
Style="{StaticResource PivotButtonStyle}" />
<zmhc:TextButton Text="Settings" Grid.Column="1" Width="58" Margin="6,0,0,0"
Checked="PivotButton_Checked" Style="{StaticResource PivotButtonStyle}" />
Style="{StaticResource PivotButtonStyle}" />
<zmhc:TextButton Text="About" Grid.Column="2" Margin="6,0,0,0"
Checked="PivotButton_Checked" Style="{StaticResource PivotButtonStyle}" />
Style="{StaticResource PivotButtonStyle}" />
</StackPanel>
</Grid>
</Border>
<Border x:Name="ContentBorder" Grid.Row="2" Padding="8">
<!--<ContentControl x:Name="ContentFrame" />-->
<TextBlock>Howdy!</TextBlock>
<Border x:Name="ContentBorder" Grid.Row="2" Padding="36,16,36,36">
<ContentControl x:Name="ContentFrame">
<ContentControl.RenderTransform>
<TranslateTransform/>
</ContentControl.RenderTransform>
<b:ContentControlExtensions.ContentChangedAnimation>
<Storyboard>
<DoubleAnimation From="-32" To="0" Duration="0:0:0.5" Storyboard.TargetProperty="RenderTransform.X">
<DoubleAnimation.EasingFunction>
<QuadraticEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation From="0" To="1.0" Duration="0:0:0.1" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</b:ContentControlExtensions.ContentChangedAnimation>
</ContentControl>
</Border>
</Grid>
</Border>
+20 -8
View File
@@ -1,8 +1,10 @@
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Interop;
using ZuneModdingHelper.Pages;
namespace ZuneModdingHelper
{
@@ -12,18 +14,23 @@ namespace ZuneModdingHelper
public partial class AppWindow
{
private IntPtr _windowHandle;
private int _selectedPivotIdx = 0;
private int _selectedPivotIdx = -1;
private readonly Type[] _pages = [typeof(ModsPage), typeof(Border), typeof(Border)];
public AppWindow()
{
Loaded += AppWindow_Loaded;
InitializeComponent();
Pivot.Loaded += Pivot_Loaded;
}
private void AppWindow_Loaded(object sender, RoutedEventArgs e)
private void Pivot_Loaded(object sender, RoutedEventArgs e)
{
foreach (var item in Pivot.Children.OfType<ToggleButton>())
item.Checked += PivotButton_Checked;
// Select MODS tab
var pivotItem = (ToggleButton)Pivot.Children[_selectedPivotIdx];
var pivotItem = (ToggleButton)Pivot.Children[0];
pivotItem.IsChecked = true;
}
@@ -59,12 +66,17 @@ namespace ZuneModdingHelper
if (newIdx == _selectedPivotIdx)
return;
var pivotItem = (ToggleButton)Pivot.Children[_selectedPivotIdx];
pivotItem.IsChecked = false;
if (_selectedPivotIdx >= 0 && _selectedPivotIdx < Pivot.Children.Count)
{
var oldPivotItem = (ToggleButton)Pivot.Children[_selectedPivotIdx];
oldPivotItem.IsChecked = false;
}
_selectedPivotIdx = newIdx;
pivotItem = (ToggleButton)Pivot.Children[_selectedPivotIdx];
pivotItem.IsChecked = true;
var newPivotItem = (ToggleButton)Pivot.Children[_selectedPivotIdx];
newPivotItem.IsChecked = true;
ContentFrame.Content = Activator.CreateInstance(_pages[_selectedPivotIdx]);
}
}
}
@@ -0,0 +1,45 @@
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
namespace ZuneModdingHelper.Behaviors;
static class ContentControlExtensions
{
/// <summary>
/// https://stackoverflow.com/questions/10831965/begin-animation-when-contentcontrol-content-is-changed
/// </summary>
public static readonly DependencyProperty ContentChangedAnimationProperty = DependencyProperty.RegisterAttached(
"ContentChangedAnimation", typeof(Storyboard), typeof(ContentControlExtensions), new PropertyMetadata(default(Storyboard), ContentChangedAnimationPropertyChangedCallback));
public static void SetContentChangedAnimation(DependencyObject element, Storyboard value)
{
element.SetValue(ContentChangedAnimationProperty, value);
}
public static Storyboard GetContentChangedAnimation(DependencyObject element)
{
return (Storyboard)element.GetValue(ContentChangedAnimationProperty);
}
private static void ContentChangedAnimationPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (dependencyObject is not ContentControl contentControl)
throw new Exception("Can only be applied to a ContentControl");
var propertyDescriptor = DependencyPropertyDescriptor.FromProperty(ContentControl.ContentProperty,
typeof(ContentControl));
propertyDescriptor.RemoveValueChanged(contentControl, ContentChangedHandler);
propertyDescriptor.AddValueChanged(contentControl, ContentChangedHandler);
}
private static void ContentChangedHandler(object sender, EventArgs eventArgs)
{
var animateObject = (FrameworkElement)sender;
var storyboard = GetContentChangedAnimation(animateObject);
storyboard.Begin(animateObject);
}
}
+73
View File
@@ -0,0 +1,73 @@
<UserControl x:Class="ZuneModdingHelper.Pages.ModsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:core="clr-namespace:ZuneModCore;assembly=ZuneModCore"
xmlns:b="clr-namespace:ZuneModdingHelper.Behaviors"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:ZuneModdingHelper.Pages"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<ListView x:Name="ModList" HorizontalContentAlignment="Stretch" BorderThickness="0"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.Resources>
<Style x:Key="MetroButton" TargetType="Button">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="8,0,0,0"/>
<Setter Property="Grid.RowSpan" Value="3"/>
</Style>
<Style x:Key="MetroAccentButton" TargetType="Button">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="8,0,0,0"/>
<Setter Property="Grid.RowSpan" Value="3"/>
</Style>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type core:Mod}">
<Border BorderThickness="0,0,0,0" Padding="8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock TextTrimming="CharacterEllipsis">
<Run Text="{Binding Title, Mode=OneWay}" FontWeight="SemiBold" FontSize="16"/>
<Run Text=" By "/><Run Text="{Binding Author, Mode=OneWay}"/>
</TextBlock>
<TextBlock Text="{Binding Description}" Grid.Row="1" FontSize="14" TextWrapping="Wrap"/>
<Button x:Name="ModResetButton" Grid.Column="1" Click="ModResetButton_Click" ToolTip="Reset"
Style="{StaticResource MetroButton}">
<mah:FontIcon Glyph="&#xE10E;" FontFamily="Segoe MDL2 Assets" Margin="4" />
</Button>
<Button x:Name="ModInstallButton" Grid.Column="2" Click="ModInstallButton_Click" ToolTip="Install"
Style="{StaticResource MetroAccentButton}">
<mah:FontIcon Glyph="&#xE73E;" FontFamily="Segoe MDL2 Assets" Margin="4" />
</Button>
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
<i:Interaction.Behaviors>
<b:FadeAnimateItemsBehavior Tick="0:0:0.05">
<b:FadeAnimateItemsBehavior.Animation>
<DoubleAnimation From="0" To="1" Duration="0:0:0.3"/>
</b:FadeAnimateItemsBehavior.Animation>
</b:FadeAnimateItemsBehavior>
</i:Interaction.Behaviors>
</ListView>
</UserControl>
+46
View File
@@ -0,0 +1,46 @@
using Microsoft.AppCenter.Analytics;
using OwlCore.AbstractUI.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ZuneModCore;
namespace ZuneModdingHelper.Pages
{
/// <summary>
/// Interaction logic for ModsPage.xaml
/// </summary>
public partial class ModsPage : UserControl
{
public ModsPage()
{
InitializeComponent();
ModList.ItemsSource = Mod.AvailableMods;
}
private async void ModInstallButton_Click(object sender, RoutedEventArgs e)
{
if (sender is FrameworkElement elem && elem.DataContext is Mod mod)
{
}
}
private async void ModResetButton_Click(object sender, RoutedEventArgs e)
{
if (sender is FrameworkElement elem && elem.DataContext is Mod mod)
{
}
}
}
}