mirror of
https://github.com/claunia/marechai.git
synced 2025-12-16 19:14:25 +00:00
Add sidebar.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using Windows.Foundation;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
@@ -8,16 +9,94 @@ namespace Marechai.App.Presentation;
|
||||
|
||||
public sealed partial class MainPage : Page
|
||||
{
|
||||
private bool _initialNewsLoaded;
|
||||
private bool _initialNewsLoaded;
|
||||
private PropertyChangedEventHandler _sidebarPropertyChangedHandler;
|
||||
|
||||
public MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContextChanged += MainPage_DataContextChanged;
|
||||
Loaded += MainPage_Loaded;
|
||||
}
|
||||
|
||||
private void MainPage_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if(DataContext is not MainViewModel viewModel) return;
|
||||
|
||||
SidebarWrapper.Width = viewModel.IsSidebarOpen ? 280 : 60;
|
||||
|
||||
if(_sidebarPropertyChangedHandler != null) return;
|
||||
|
||||
_sidebarPropertyChangedHandler = (_, propArgs) =>
|
||||
{
|
||||
if(propArgs.PropertyName != nameof(MainViewModel.IsSidebarOpen)) return;
|
||||
|
||||
AnimateSidebarWidth(((MainViewModel)DataContext).IsSidebarOpen);
|
||||
};
|
||||
|
||||
((INotifyPropertyChanged)viewModel).PropertyChanged += _sidebarPropertyChangedHandler;
|
||||
}
|
||||
|
||||
void AnimateSidebarWidth(bool isOpen)
|
||||
{
|
||||
double start = SidebarColumn.Width.Value;
|
||||
double end = isOpen ? 280 : 60;
|
||||
|
||||
if(Math.Abs(start - end) < 0.1) return;
|
||||
|
||||
// If expanding, show content immediately
|
||||
if(isOpen && DataContext is MainViewModel vm) vm.SidebarContentVisible = true;
|
||||
|
||||
const int durationMs = 250;
|
||||
const int fps = 60;
|
||||
var steps = (int)(durationMs / (1000.0 / fps));
|
||||
var currentStep = 0;
|
||||
|
||||
var timer = new DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromMilliseconds(1000.0 / fps)
|
||||
};
|
||||
|
||||
timer.Tick += (_, _) =>
|
||||
{
|
||||
currentStep++;
|
||||
double t = (double)currentStep / steps;
|
||||
|
||||
// Ease in-out cubic
|
||||
double eased = t < 0.5 ? 4 * t * t * t : 1 - Math.Pow(-2 * t + 2, 3) / 2;
|
||||
double value = start + (end - start) * eased;
|
||||
SidebarColumn.Width = new GridLength(value, GridUnitType.Pixel);
|
||||
SidebarWrapper.Width = value;
|
||||
|
||||
if(currentStep >= steps)
|
||||
{
|
||||
SidebarColumn.Width = new GridLength(end, GridUnitType.Pixel);
|
||||
SidebarWrapper.Width = end;
|
||||
timer.Stop();
|
||||
|
||||
// After collapse animation completes, hide sidebar content
|
||||
if(!isOpen && DataContext is MainViewModel vm) vm.SidebarContentVisible = false;
|
||||
}
|
||||
};
|
||||
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
private void MainPage_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
|
||||
{
|
||||
if(args.NewValue is MainViewModel vm && _sidebarPropertyChangedHandler == null)
|
||||
{
|
||||
SidebarWrapper.Width = vm.IsSidebarOpen ? 280 : 60;
|
||||
|
||||
_sidebarPropertyChangedHandler = (_, propArgs) =>
|
||||
{
|
||||
if(propArgs.PropertyName != nameof(MainViewModel.IsSidebarOpen)) return;
|
||||
AnimateSidebarWidth(vm.IsSidebarOpen);
|
||||
};
|
||||
|
||||
((INotifyPropertyChanged)vm).PropertyChanged += _sidebarPropertyChangedHandler;
|
||||
}
|
||||
|
||||
if(_initialNewsLoaded) return;
|
||||
|
||||
if(args.NewValue is MainViewModel viewModel && viewModel.NewsViewModel is not null)
|
||||
|
||||
Reference in New Issue
Block a user