mirror of
https://github.com/denglihong2007/CRSim
synced 2026-05-12 22:22:10 +08:00
feat: 集成化的窗口管理器
This commit is contained in:
16
CRSim.ScreenSimulator/Abstractions/IScreenViewModel.cs
Normal file
16
CRSim.ScreenSimulator/Abstractions/IScreenViewModel.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using CRSim.Core.Abstractions;
|
||||
using CRSim.Core.Models;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace CRSim.ScreenSimulator.Abstractions
|
||||
{
|
||||
public interface IScreenViewModel
|
||||
{
|
||||
ITimeService TimeService { get; }
|
||||
Dispatcher UIDispatcher { get; set; }
|
||||
void LoadData(Station station, string ticketCheck, string platform);
|
||||
string? Text { get; set; }
|
||||
Uri Video { get; set; }
|
||||
int Location { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace CRSim.ScreenSimulator.Models
|
||||
{
|
||||
public class ScreenInfo
|
||||
{
|
||||
public required Guid SessionID { get; set; }
|
||||
public required string SelectedStyle { get; set; }
|
||||
public string? Text { get; set; }
|
||||
public string? Video { get; set; }
|
||||
public string? SelectedStationName { get; set; }
|
||||
public string? SelectedTicketCheck { get; set; }
|
||||
public string? SelectedPlatformName { get; set; }
|
||||
public int? SelectedLoaction { get; set; }
|
||||
}
|
||||
}
|
||||
17
CRSim.ScreenSimulator/Models/Session.cs
Normal file
17
CRSim.ScreenSimulator/Models/Session.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using CRSim.Core.Models;
|
||||
|
||||
namespace CRSim.ScreenSimulator.Models
|
||||
{
|
||||
public class Session
|
||||
{
|
||||
public required Guid ID { get; set; }
|
||||
public required string StyleName { get; set; }
|
||||
public required DateTime SimulateTime { get; set; }
|
||||
public string? Text { get; set; }
|
||||
public Uri? Video { get; set; }
|
||||
public Station? Station { get; set; }
|
||||
public string? TicketCheck { get; set; }
|
||||
public string? PlatformName { get; set; }
|
||||
public int? Loaction { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,50 +1,63 @@
|
||||
using CRSim.Core.Abstractions;
|
||||
using CRSim.Core.Enums;
|
||||
using CRSim.Core.Models;
|
||||
using CRSim.Core.Models.Plugin;
|
||||
using CRSim.ScreenSimulator.Abstractions;
|
||||
using CRSim.ScreenSimulator.Models;
|
||||
using CRSim.ScreenSimulator.Views;
|
||||
using System.Windows;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Windows.Controls;
|
||||
using Windows.System;
|
||||
|
||||
namespace CRSim.ScreenSimulator
|
||||
{
|
||||
public class StyleManager
|
||||
{
|
||||
public static List<PluginInfo> StyleInfos => [.. IPluginService.LoadedPlugins.Where(x => x.Manifest.Type == "ScreenStyle" && x.LoadStatus == PluginLoadStatus.Loaded)];
|
||||
public static IServiceProvider ServiceProvider;
|
||||
private static IDatabaseService _databaseService;
|
||||
public StyleManager(IServiceProvider serviceProvider,IDatabaseService databaseService)
|
||||
public List<PluginInfo> StyleInfos => [.. IPluginService.LoadedPlugins.Where(x => x.Manifest.Type == "ScreenStyle" && x.LoadStatus == PluginLoadStatus.Loaded)];
|
||||
|
||||
public static IServiceProvider ServiceProvider { get; set; }
|
||||
|
||||
public ObservableCollection<SimulatorWindow> ActiveWindows { get; set; } = [];
|
||||
|
||||
public DispatcherQueue DispatcherQueue { get; set; } = DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
public StyleManager(IServiceProvider serviceProvider)
|
||||
{
|
||||
ServiceProvider = serviceProvider;
|
||||
_databaseService = databaseService;
|
||||
}
|
||||
public static void ShowWindow(Type page, Station station, string ticketCheck, string platform,string? text,int location,string? video,DateTime dateTime)
|
||||
public void ShowWindow(Type page, Session session)
|
||||
{
|
||||
Thread thread = new(() =>
|
||||
{
|
||||
Page viewInstance = (Page)ServiceProvider.GetService(page);
|
||||
var viewModel = ((dynamic)viewInstance).ViewModel;
|
||||
if (viewInstance.DataContext is IScreenViewModel viewModel)
|
||||
{
|
||||
var timeService = viewModel.TimeService;
|
||||
timeService.SimulateTime = session.SimulateTime;
|
||||
timeService.Start();
|
||||
|
||||
var timeService = ((ITimeService)viewModel.TimeService);
|
||||
timeService.SimulateTime = dateTime;
|
||||
timeService.Start();
|
||||
|
||||
viewModel.UIDispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
|
||||
if (text != null)
|
||||
{
|
||||
viewModel.Text = text;
|
||||
viewModel.UIDispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
|
||||
if (session.Text != null)
|
||||
{
|
||||
viewModel.Text = session.Text;
|
||||
}
|
||||
if (session.Loaction != null && session.Loaction != 0)
|
||||
{
|
||||
viewModel.Location = session.Loaction.Value;
|
||||
}
|
||||
if (session.Video != null)
|
||||
{
|
||||
viewModel.Video = session.Video;
|
||||
}
|
||||
viewModel.LoadData(session.Station, session.TicketCheck, session.PlatformName);
|
||||
var win = new SimulatorWindow(viewInstance, timeService, this, session);
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
ActiveWindows.Add(win);
|
||||
});
|
||||
win.Show();
|
||||
System.Windows.Threading.Dispatcher.Run();
|
||||
}
|
||||
if (location != 0)
|
||||
{
|
||||
viewModel.Location = location;
|
||||
}
|
||||
if (video != null)
|
||||
{
|
||||
viewModel.Video = video;
|
||||
}
|
||||
viewModel.LoadData(station, ticketCheck, platform);
|
||||
var win = new SimulatorWindow(viewInstance, timeService);
|
||||
win.Show();
|
||||
System.Windows.Threading.Dispatcher.Run();
|
||||
});
|
||||
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
|
||||
@@ -4,12 +4,13 @@ using CRSim.ScreenSimulator.Models;
|
||||
using System.Windows;
|
||||
using System.Collections.ObjectModel;
|
||||
using CRSim.Core.Abstractions;
|
||||
using CRSim.ScreenSimulator.Abstractions;
|
||||
|
||||
namespace CRSim.ScreenSimulator.ViewModels
|
||||
{
|
||||
public partial class BaseScreenViewModel : ObservableObject
|
||||
public partial class BaseScreenViewModel : ObservableObject,IScreenViewModel
|
||||
{
|
||||
public readonly ITimeService TimeService;
|
||||
public ITimeService TimeService { get; set; }
|
||||
public readonly Settings _settings;
|
||||
public readonly TaskCompletionSource<bool> DataLoaded = new();
|
||||
[ObservableProperty]
|
||||
@@ -24,6 +25,8 @@ namespace CRSim.ScreenSimulator.ViewModels
|
||||
private string _thisPlatform;
|
||||
[ObservableProperty]
|
||||
private string _thisTicketCheck;
|
||||
[ObservableProperty]
|
||||
private Uri _video;
|
||||
public ObservableCollection<TrainInfo> ScreenA { get; private set; } = [];
|
||||
public ObservableCollection<TrainInfo> ScreenB { get; private set; } = [];
|
||||
public System.Windows.Threading.Dispatcher UIDispatcher { get; set; }
|
||||
@@ -1,13 +1,14 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CRSim.Core.Abstractions;
|
||||
using CRSim.Core.Models;
|
||||
using CRSim.ScreenSimulator.Abstractions;
|
||||
using CRSim.ScreenSimulator.Models;
|
||||
|
||||
namespace CRSim.ScreenSimulator.ViewModels
|
||||
{
|
||||
public partial class MetroPlatformScreenViewModel : ObservableObject
|
||||
public partial class MetroPlatformScreenViewModel : ObservableObject, IScreenViewModel
|
||||
{
|
||||
public readonly ITimeService TimeService;
|
||||
public ITimeService TimeService { get; set; }
|
||||
public readonly Settings _settings;
|
||||
[ObservableProperty]
|
||||
private DateTime _currentTime = new();
|
||||
@@ -19,6 +20,8 @@ namespace CRSim.ScreenSimulator.ViewModels
|
||||
private string _text;
|
||||
[ObservableProperty]
|
||||
private Uri _video;
|
||||
[ObservableProperty]
|
||||
public int _location;
|
||||
public System.Windows.Threading.Dispatcher UIDispatcher { get; set; }
|
||||
public List<TrainInfo> TrainInfos { get; set; } = [];
|
||||
public MetroPlatformScreenViewModel(ITimeService timeService, ISettingsService settingsService)
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
ResizeMode="NoResize"
|
||||
WindowStyle="None"
|
||||
AllowsTransparency="True"
|
||||
MouseDown="Window_MouseDown">
|
||||
MouseDown="Window_MouseDown"
|
||||
Closed="Window_Closed">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -28,7 +29,7 @@
|
||||
<TextBlock x:Name="SpeedText" Text="1x" FontSize="22" VerticalAlignment="Center" Margin="6,0"/>
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="20" VerticalAlignment="Center" MouseLeftButtonDown="IncreaseSpeed"/>
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="20"
|
||||
VerticalAlignment="Center" Margin="12,0,2,0" MouseLeftButtonDown="Close"/>
|
||||
VerticalAlignment="Center" Margin="12,0,2,0" MouseLeftButtonDown="CloseWindow"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using CRSim.Core.Abstractions;
|
||||
using CRSim.ScreenSimulator.Converters;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CRSim.Core.Abstractions;
|
||||
using CRSim.ScreenSimulator.Models;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
@@ -10,13 +11,16 @@ namespace CRSim.ScreenSimulator.Views
|
||||
public partial class SimulatorWindow : Window
|
||||
{
|
||||
private readonly ITimeService _timeService;
|
||||
|
||||
public SimulatorWindow(Page page,ITimeService timeService)
|
||||
private readonly StyleManager _styleManager;
|
||||
public Session Session { get; }
|
||||
public SimulatorWindow(Page page,ITimeService timeService,StyleManager styleManager,Session session)
|
||||
{
|
||||
Session = session;
|
||||
InitializeComponent();
|
||||
RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);
|
||||
contentFrame.Content = page;
|
||||
_timeService = timeService;
|
||||
_styleManager = styleManager;
|
||||
foreach (var resource in page.Resources.Values)
|
||||
{
|
||||
if (resource is IHasTimeService needsTime)
|
||||
@@ -48,9 +52,31 @@ namespace CRSim.ScreenSimulator.Views
|
||||
}
|
||||
}
|
||||
|
||||
private void Close(object sender, MouseButtonEventArgs e)
|
||||
private void Window_Closed(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
_styleManager.DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
_styleManager.ActiveWindows.Remove(this);
|
||||
});
|
||||
}
|
||||
|
||||
public void FoucsWindow(object o,object s)
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
WindowState = WindowState.Normal;
|
||||
Activate();
|
||||
Topmost = true;
|
||||
Topmost = false;
|
||||
Focus();
|
||||
});
|
||||
}
|
||||
public void CloseWindow(object o, object s)
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
Close();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
namespace CRSim.ViewModels;
|
||||
using System.Windows;
|
||||
|
||||
namespace CRSim.ViewModels;
|
||||
public partial class DashboardPageViewModel : ObservableObject
|
||||
{
|
||||
|
||||
[RelayCommand]
|
||||
private void AddItem()
|
||||
public StyleManager StyleManager { get; }
|
||||
public DashboardPageViewModel(StyleManager styleManager)
|
||||
{
|
||||
StyleManager = styleManager;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
using CRSim.Core.Models.Plugin;
|
||||
using CRSim.ScreenSimulator.Models;
|
||||
|
||||
namespace CRSim.ViewModels;
|
||||
|
||||
public partial class ScreenSimulatorPageViewModel(IServiceProvider serviceProvider, IDatabaseService databaseService) : ObservableObject
|
||||
public partial class ScreenSimulatorPageViewModel(IEnumerable<PluginBase> plugins, IDatabaseService databaseService, StyleManager styleManager) : ObservableObject
|
||||
{
|
||||
public string PageTitle = "引导屏模拟";
|
||||
public List<PluginInfo> StyleInfos => StyleManager.StyleInfos;
|
||||
public List<PluginInfo> StyleInfos => styleManager.StyleInfos;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial PluginInfo SelectedStyle { get; set; }
|
||||
|
||||
@@ -30,6 +32,7 @@ public partial class ScreenSimulatorPageViewModel(IServiceProvider serviceProvid
|
||||
public ObservableCollection<string> TicketChecks { get; private set; } = [];
|
||||
public ObservableCollection<Platform> Platforms { get; private set; } = [];
|
||||
public ObservableCollection<int> Locations { get; private set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Text { get; set; }
|
||||
|
||||
@@ -46,7 +49,8 @@ public partial class ScreenSimulatorPageViewModel(IServiceProvider serviceProvid
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsStartSimulationAvailable { get; private set; } = false;
|
||||
private PluginBase SelectedStylePlugin => serviceProvider.GetServices<PluginBase>().Where(x => x.Info == SelectedStyle).FirstOrDefault();
|
||||
|
||||
private PluginBase SelectedStylePlugin => plugins.Where(x => x.Info == SelectedStyle).FirstOrDefault();
|
||||
|
||||
public DateTimeOffset SelectedDate = DateTime.Today;
|
||||
|
||||
@@ -135,16 +139,22 @@ public partial class ScreenSimulatorPageViewModel(IServiceProvider serviceProvid
|
||||
//Video = Path;
|
||||
}
|
||||
[RelayCommand]
|
||||
public async Task StartSimulation()
|
||||
public void StartSimulation()
|
||||
{
|
||||
StyleManager.ShowWindow(SelectedStylePlugin.View,
|
||||
databaseService.GetStationByName(SelectedStationName),
|
||||
TicketCheckNeeded ? SelectedTicketCheck : string.Empty,
|
||||
PlatformNeeded ? SelectedPlatformName : string.Empty,
|
||||
(TextNeeded && Text != string.Empty) ? Text : null,
|
||||
(LocationNeeded && SelectedLoaction != 0) ? SelectedLoaction : 0,
|
||||
(VideoNeeded && Video != string.Empty) ? Video : null,
|
||||
SelectedDate.Add(SelectedTime).DateTime);
|
||||
// 构建 Session 对象
|
||||
var session = new Session
|
||||
{
|
||||
ID = Guid.NewGuid(),
|
||||
StyleName = SelectedStyle.Manifest.Name,
|
||||
SimulateTime = SelectedDate.Add(SelectedTime).DateTime,
|
||||
Text = (TextNeeded && !string.IsNullOrWhiteSpace(Text)) ? Text : null,
|
||||
Video = (VideoNeeded && !string.IsNullOrWhiteSpace(Video)) ? new Uri(Video) : null,
|
||||
Station = StationNeeded ? databaseService.GetStationByName(SelectedStationName) : null,
|
||||
TicketCheck = TicketCheckNeeded ? SelectedTicketCheck : string.Empty,
|
||||
PlatformName = PlatformNeeded ? SelectedPlatformName : string.Empty,
|
||||
Loaction = (LocationNeeded && SelectedLoaction != 0) ? SelectedLoaction : 0
|
||||
};
|
||||
styleManager.ShowWindow(SelectedStylePlugin.View, session);
|
||||
}
|
||||
|
||||
private void CheckCanStart()
|
||||
|
||||
@@ -4,11 +4,34 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:CRSim.Views"
|
||||
xmlns:winui="using:CommunityToolkit.WinUI"
|
||||
xmlns:screensim="using:CRSim.ScreenSimulator.Views"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<TextBox Text="1"/>
|
||||
</Grid>
|
||||
<ScrollViewer Padding="36">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="活动的引导屏"/>
|
||||
<Border Style="{StaticResource ListViewBorder}">
|
||||
<ListView ItemsSource="{x:Bind ViewModel.StyleManager.ActiveWindows,Mode=OneWay}" SelectionMode="None">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="screensim:SimulatorWindow">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{x:Bind Session.StyleName}" VerticalAlignment="Center"/>
|
||||
<Button Grid.Column="2" Style="{StaticResource AccentButtonStyle}" Height="32"
|
||||
Margin="0,0,4,0" Content="{winui:FontIcon FontSize=16, Glyph=}" Click="{x:Bind FoucsWindow}"/>
|
||||
<Button Grid.Column="3" Height="32" Content="{winui:FontIcon FontSize=16, Glyph=}" Click="{x:Bind CloseWindow}"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Page>
|
||||
|
||||
Reference in New Issue
Block a user