mirror of
https://github.com/ZuneDev/ZuneModdingHelper.git
synced 2026-07-27 13:12:21 -07:00
Implement navigation with animations
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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="" 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="" 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>
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user