mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-12 13:28:33 +00:00
Workshop - Implemented image gallery dialog
This commit is contained in:
parent
e304d67035
commit
9393bf2b68
@ -107,7 +107,7 @@ public class ContentDialogBuilder
|
||||
_contentDialog.IsSecondaryButtonEnabled = builder.Command.CanExecute(builder.CommandParameter);
|
||||
builder.Command.CanExecuteChanged += (_, _) => _contentDialog.IsSecondaryButtonEnabled = builder.Command.CanExecute(builder.CommandParameter);
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
|
||||
xmlns:details="clr-namespace:Artemis.UI.Screens.Workshop.Entries.Details"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Entries.Details.EntryImagesDialogView"
|
||||
x:DataType="details:EntryImagesDialogViewModel"
|
||||
Margin="-25 -63 -25 -25">
|
||||
<Image asyncImageLoader:ImageLoader.Source="{CompiledBinding CurrentImage.Url}" Stretch="None"/>
|
||||
</UserControl>
|
||||
@ -0,0 +1,14 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Entries.Details;
|
||||
|
||||
public partial class EntryImagesDialogView : ReactiveUserControl<EntryImagesDialogViewModel>
|
||||
{
|
||||
public EntryImagesDialogView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Disposables;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Shared;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Entries.Details;
|
||||
|
||||
public partial class EntryImagesDialogViewModel : ContentDialogViewModelBase
|
||||
{
|
||||
[Notify] private EntryImageViewModel _currentImage;
|
||||
private readonly IInputService _inputService;
|
||||
|
||||
public EntryImagesDialogViewModel(ObservableCollection<EntryImageViewModel> images, EntryImageViewModel startImage, IInputService inputService)
|
||||
{
|
||||
_currentImage = startImage;
|
||||
_inputService = inputService;
|
||||
|
||||
Images = images;
|
||||
Previous = ReactiveCommand.Create(() => CurrentImage = Images[(Images.IndexOf(CurrentImage) - 1 + Images.Count) % Images.Count]);
|
||||
Next = ReactiveCommand.Create(() => CurrentImage = Images[(Images.IndexOf(CurrentImage) + 1) % Images.Count]);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
if (ContentDialog == null)
|
||||
return;
|
||||
|
||||
_inputService.KeyboardKeyDown += InputServiceOnKeyboardKeyDown;
|
||||
ContentDialog.Closing += ContentDialogOnClosing;
|
||||
Disposable.Create(() =>
|
||||
{
|
||||
_inputService.KeyboardKeyDown -= InputServiceOnKeyboardKeyDown;
|
||||
ContentDialog.Closing -= ContentDialogOnClosing;
|
||||
}).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
private void InputServiceOnKeyboardKeyDown(object? sender, ArtemisKeyboardKeyEventArgs e)
|
||||
{
|
||||
// Leveraging InputService to avoid issues with which control has focus
|
||||
if (e.Key == KeyboardKey.ArrowRight)
|
||||
Next.Execute().Subscribe();
|
||||
else if (e.Key == KeyboardKey.ArrowLeft)
|
||||
Previous.Execute().Subscribe();
|
||||
else if (e.Key == KeyboardKey.Escape)
|
||||
ContentDialog?.Hide(ContentDialogResult.None);
|
||||
}
|
||||
|
||||
private void ContentDialogOnClosing(ContentDialog sender, ContentDialogClosingEventArgs args)
|
||||
{
|
||||
args.Cancel = args.Result != ContentDialogResult.None;
|
||||
}
|
||||
|
||||
public ObservableCollection<EntryImageViewModel> Images { get; }
|
||||
public ReactiveCommand<Unit, EntryImageViewModel> Previous { get; }
|
||||
public ReactiveCommand<Unit, EntryImageViewModel> Next { get; }
|
||||
}
|
||||
@ -2,14 +2,12 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
||||
xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
|
||||
xmlns:details="clr-namespace:Artemis.UI.Screens.Workshop.Entries.Details"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Entries.Details.EntryImagesView"
|
||||
x:DataType="details:EntryImagesViewModel">
|
||||
<ScrollViewer Classes="with-padding" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl ItemsSource="{CompiledBinding Images}" Width="300">
|
||||
<ItemsControl ItemsSource="{CompiledBinding Images}">
|
||||
<ItemsControl.Styles>
|
||||
<Styles>
|
||||
<Style Selector="ItemsControl > ContentPresenter">
|
||||
@ -20,6 +18,11 @@
|
||||
</Style>
|
||||
</Styles>
|
||||
</ItemsControl.Styles>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ContentPresenter Content="{CompiledBinding}" Cursor="Hand" PointerPressed="InputElement_OnPointerPressed"></ContentPresenter>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel />
|
||||
|
||||
@ -1,13 +1,23 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Entries.Details;
|
||||
|
||||
public partial class EntryImagesView : UserControl
|
||||
public partial class EntryImagesView : ReactiveUserControl<EntryImagesViewModel>
|
||||
{
|
||||
public EntryImagesView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InputElement_OnPointerPressed(object? sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (sender is not IDataContextProvider contextProvider)
|
||||
return;
|
||||
if (contextProvider.DataContext is not EntryImageViewModel entryImageViewModel)
|
||||
return;
|
||||
|
||||
ViewModel?.ShowImages(entryImageViewModel);
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,30 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.WebClient.Workshop;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Entries.Details;
|
||||
|
||||
public class EntryImagesViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IWindowService _windowService;
|
||||
public ObservableCollection<EntryImageViewModel> Images { get; }
|
||||
|
||||
public EntryImagesViewModel(IEntryDetails entryDetails)
|
||||
public EntryImagesViewModel(IEntryDetails entryDetails, IWindowService windowService)
|
||||
{
|
||||
_windowService = windowService;
|
||||
Images = new ObservableCollection<EntryImageViewModel>(entryDetails.Images.Select(i => new EntryImageViewModel(i)));
|
||||
}
|
||||
|
||||
public async Task ShowImages(EntryImageViewModel image)
|
||||
{
|
||||
await _windowService.CreateContentDialog()
|
||||
.WithViewModel(out EntryImagesDialogViewModel vm, Images, image)
|
||||
.HavingPrimaryButton(b => b.WithText("Previous").WithCommand(vm.Previous))
|
||||
.HavingSecondaryButton(b => b.WithText("Next").WithCommand(vm.Next))
|
||||
.WithFullScreen()
|
||||
.ShowAsync();
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,8 @@
|
||||
xmlns:styling="clr-namespace:FluentAvalonia.Styling;assembly=FluentAvalonia"
|
||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||
xmlns:aedit="using:AvaloniaEdit"
|
||||
xmlns:aedit2="using:AvaloniaEdit.Editing">
|
||||
xmlns:aedit2="using:AvaloniaEdit.Editing"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia">
|
||||
<!-- Third party styles -->
|
||||
<styling:FluentAvaloniaTheme PreferSystemTheme="False" PreferUserAccentColor="True"/>
|
||||
<avalonia:MaterialIconStyles />
|
||||
@ -24,6 +25,17 @@
|
||||
<Setter Property="SelectionForeground" Value="{DynamicResource TextOnAccentFillColorSelectedTextBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="controls|ContentDialog.fullscreen controls|FABorder#BackgroundElement">
|
||||
<Setter Property="MaxWidth" Value="99999"></Setter>
|
||||
<Setter Property="MaxHeight" Value="99999"></Setter>
|
||||
<Setter Property="Margin" Value="100"></Setter>
|
||||
</Style>
|
||||
|
||||
<Style Selector="controls|ContentDialog.fullscreen ScrollViewer#ContentScrollViewer">
|
||||
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled"></Setter>
|
||||
<Setter Property="VerticalScrollBarVisibility" Value="Disabled"></Setter>
|
||||
</Style>
|
||||
|
||||
<Styles.Resources>
|
||||
<ResourceDictionary>
|
||||
<FontFamily x:Key="RobotoMono">avares://Artemis.UI/Assets/Fonts#Roboto Mono</FontFamily>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user